Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Базы данных под .NET > Выборка из таблицы уникального значения


Автор: Nord 18.8.2007, 10:32
Приветствую!    Встолкнулся вот со следующей проблемой

Имеется таблица: 

     |__id_cat__|_id_key__|
     |    1           |      5         | 
     |    1           |      2         |
     |    1           |      3         |
     |    2           |      1         |
     |    2           |      2         |
     |    2           |      3         |
     |    2           |      4         |
    
Необходимо выбрать только те id_cat, которые имеют уникальную пару из двух id_key

Например: нужно отобрать id_cat,  у которого id_key=3 и id_key=4 - соответственно это id_cat 2, т.к. id_cat 1 не содержит id_key=4. А для  id_key=3 и id_key=5 это будет  id_cat 1, т.к.  id_cat 2 не содержит id_key=4.

Надеюсь, что понятно сформировал вопрос....
Должно как-то просто быть, только вот знаний не хватает запрос составить...

Автор: thomas 18.8.2007, 10:58
Nord, 
Код

SELECT id_cat FROM tableName WHERE id_key = 3 AND id_key = 4;

Автор: Idsa 18.8.2007, 11:22
Цитата(thomas @  18.8.2007,  10:58 Найти цитируемый пост)
SELECT id_cat FROM tableName WHERE id_key = 3 AND id_key = 4;

smile

Автор: Nord 18.8.2007, 12:31
Цитата(thomas @ 18.8.2007,  10:58)
Nord, 
Код

SELECT id_cat FROM tableName WHERE id_key = 3 AND id_key = 4;

Я так уже пробовал - не выводит ничего в результате запроса

Автор: Idsa 18.8.2007, 18:12
Вот запрос, выполняющий поставленную задачу:
Код

SELECT distinct id_cat FROM tableName AS X WHERE 3 IN (SELECT id_key FROM tableName WHERE id_cat = X.id_cat) AND 4 IN (SELECT id_key FROM tableName WHERE id_cat = X.id_cat);

, но как-то уж жутко неоптимально. Хотелось бы вот эту часть: 3 IN (SELECT id_key FROM tableName WHERE id_cat = X.id_cat) AND 4 IN (SELECT id_key FROM tableName WHERE id_cat = X.id_cat) переписать вот так: (3, 4) in (SELECT id_key FROM tableName WHERE id_cat = X.id_cat)... однако оператор IN позволяет сравнивать только значение и множество (а в данном случае сравниваются 2 множества). Знатоки SQL, может, подскажете, как этот запрос можно оптимизировать?

Автор: tol05 18.8.2007, 18:34
Код

SELECT id_cat FROM tableName WHERE id_key = 3 OR id_key = 4

Автор: Idsa 18.8.2007, 18:42
Цитата(Nord @  18.8.2007,  10:32 Найти цитируемый пост)
Необходимо выбрать только те id_cat, которые имеют уникальную пару из двух id_key

Цитата(tol05 @  18.8.2007,  18:34 Найти цитируемый пост)
SELECT id_cat FROM tableName WHERE id_key = 3 OR id_key = 4

smile

Автор: andrx 20.8.2007, 09:12
Можно так :

SELECT * FROM
( SELECT [id_cat] FROM [tableName][T1] GROUP BY [id_cat],[id_key] HAVING ([id_key] IN (3,4)) )[T2]
GROUP BY [id_cat] HAVING COUNT(*)>=2

-------------
в конструкции HAVING ([id_key] IN (3,4) - указывай список id_key
а в конструкции HAVING COUNT(*)>=2 - указывай количество елементов списка id_key


если прислушаться к QA, то этот запрос оптимальнее


Доработанный запрос:
Код

SELECT [id_cat] FROM [tableName] WHERE ([id_key] IN (3,4)) GROUP BY [id_cat] HAVING COUNT(*)>=2

Автор: Idsa 20.8.2007, 09:43
Цитата(andrx @  20.8.2007,  09:12 Найти цитируемый пост)
SELECT [id_cat] FROM [tableName] WHERE (id_key IN (3,4)) 

Тоже smile

Автор: andrx 20.8.2007, 09:52
Idsa  согласен
не сразу понял, что хотел Nord 

запрос исправлен

Добавлено через 8 минут и 7 секунд
Idsa
Цитата

переписать вот так: (3, 4) in (SELECT id_key FROM tableName WHERE id_cat = X.id_cat)


даже если бы это было возможно, я думаю что такая конструкция работала бы через OR, а нужен обязательно AND

Автор: Idsa 20.8.2007, 10:45
Оптимальный запрос выглядит вот так:
Код

select t1.id_cat from 

    ( select * from [table] where id_key = 3 ) as t1

    inner join

    ( select * from [table] where id_key = 4 ) as t2

    on t1.id_cat = t2.id_cat

Его отправил мне по личке топикстартер.

Мой вариант использовал коррелированные подзапросы, что делает его гораздо более медленным. Да и вообще, в подобных ситуациях нужно использовать именно inner join.

Автор: Nord 22.8.2007, 15:38
Цитата(Idsa @ 20.8.2007,  10:45)
Оптимальный запрос выглядит вот так:
Код

select t1.id_cat from 

    ( select * from [table] where id_key = 3 ) as t1

    inner join

    ( select * from [table] where id_key = 4 ) as t2

    on t1.id_cat = t2.id_cat

Его отправил мне по личке топикстартер.

Мой вариант использовал коррелированные подзапросы, что делает его гораздо более медленным. Да и вообще, в подобных ситуациях нужно использовать именно inner join.

Idsa, спасибо, что разместил здесь это. Вобщем проблема вроде бы как решена  smile  

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)