Эффективный способ выбрать все значения из одного столбца, а не из другого столбца - PullRequest
9 голосов
/ 05 января 2012

Мне нужно вернуть все значения из colA, которых нет в colB из mytable. Я использую:

SELECT DISTINCT(colA) FROM mytable WHERE colA NOT IN (SELECT colB FROM mytable)

Работает, однако выполнение запроса занимает слишком много времени.

Есть ли более эффективный способ сделать это?

Ответы [ 3 ]

15 голосов
/ 05 января 2012

В стандартном SQL есть без скобок в DISTINCT colA. DISTINCT не является функцией.

SELECT DISTINCT colA
FROM   mytable
WHERE  colA NOT IN (SELECT DISTINCT colB FROM mytable);

Также добавлено DISTINCT в суб-выбор. Если у вас много дубликатов, это может ускорить запрос.

CTE может быть быстрее, в зависимости от вашей СУБД. Я дополнительно демонстрирую LEFT JOIN как альтернативу для исключения значений в valB и альтернативный способ получения различных значений с помощью GROUP BY:

WITH x AS (SELECT colB FROM mytable GROUP BY colB)
SELECT m.colA
FROM   mytable m
LEFT   JOIN x ON x.colB = m.colA
WHERE  x.colB IS NULL
GROUP  BY m.colA;

Или, упрощенный далее, и с простым подзапросом (вероятно, самый быстрый):

SELECT DISTINCT m.colA
FROM   mytable m
LEFT   JOIN mytable x ON x.colB = m.colA
WHERE  x.colB IS NULL;

Существует в основном 4 метода для исключения строк с ключами, присутствующими в другой (или той же) таблице:

Решающим фактором для скорости будет indexes . Вам нужно иметь индексы на colA и colB, чтобы этот запрос был быстрым.

6 голосов
/ 05 января 2012

Вы можете использовать exists:

select distinct
    colA
from
    mytable m1
where
    not exists (select 1 from mytable m2 where m2.colB = m1.colA)

exists делает полусоединение для быстрого сопоставления значений.not in завершает весь набор результатов и затем or на нем.exists обычно быстрее для значений в таблицах.

0 голосов
/ 05 января 2012

Вы можете использовать оператор EXCEPT, который эффективно выводит два запроса SELECT.EXCEPT DISTINCT вернет только уникальные значения.Оператор Oracle MINUS эквивалентен EXCEPT DISTINCT.

...