Выберите значения в SQL, которые не имеют других соответствующих значений, кроме тех, которые я ищу - PullRequest
1 голос
/ 09 июля 2009

В моей базе данных есть таблица:

Name  |  Element
 1         2
 1         3
 4         2
 4         3
 4         5

Мне нужно сделать запрос, который для ряда аргументов выберет значение Name, которое имеет справа эти и только эти значения. Например.: Аргументы 2 и 3, запрос должен возвращать только 1, а не 4 (потому что 4 также имеет 5). Для аргументов 2,3,5 он должен вернуть 4.

Мой запрос выглядит так:

SELECT name FROM aggregations WHERE (element=2 and name in (select name from aggregations where element=3))

Что мне нужно добавить к этому запросу, чтобы он не возвращал 4?

Ответы [ 3 ]

8 голосов
/ 09 июля 2009

Простой способ сделать это:

SELECT name
FROM aggregations
WHERE element IN (2,3)
GROUP BY name
HAVING COUNT(element) = 2

Если вы хотите добавить больше, вам нужно изменить и часть IN (2,3), и часть HAVING:

SELECT name
FROM aggregations
WHERE element IN (2,3,5)
GROUP BY name
HAVING COUNT(element) = 3

Более надежный способ - проверить все, чего нет в вашем наборе:

SELECT name
FROM aggregations
WHERE NOT EXISTS (
  SELECT DISTINCT a.element 
  FROM aggregations a
  WHERE a.element NOT IN (2,3,5)
  AND a.name = aggregations.name
)
GROUP BY name
HAVING COUNT(element) = 3

Хотя это не очень эффективно.

1 голос
/ 09 июля 2009

Создайте временную таблицу, заполните ее значениями и сделайте запрос, например:

SELECT  name
FROM    (
        SELECT  DISTINCT name
        FROM    aggregations
        ) n
WHERE   NOT EXISTS
        (
        SELECT  1
        FROM    (
                SELECT  element
                FROM    aggregations aii
                WHERE   aii.name = n.name
                ) ai
        FULL OUTER JOIN
                temptable tt
        ON      tt.element = ai.element
        WHERE   ai.element IS NULL OR tt.element IS NULL
        )

Это более эффективно, чем использование COUNT(*), так как он прекратит проверку name, как только обнаружит первую строку, которая не соответствует (либо в aggregations, либо в temptable)

0 голосов
/ 09 июля 2009

Это не проверено, но обычно я делаю это с помощью запроса в моем предложении where для небольшого количества данных. Обратите внимание, что это не эффективно для большого количества записей.

SELECT ag1.Name FROM aggregations ag1 
WHERE ag1.Element IN (2,3)
AND 0 = (select COUNT(ag2.Name) 
    FROM aggregatsions ag2 
    WHERE ag1.Name = ag2.Name
        AND ag2.Element NOT IN (2,3)
)
GROUP BY ag1.name;

Это говорит: «Дайте мне все имена, которые содержат элементы, которые я хочу, но не имеют записей с элементами, которые я не хочу»

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...