12

我需要返回所有colA不在colBfrom中的值mytable。我在用:

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

它正在工作,但是查询需要很长时间才能完成。

有没有更有效的方法来做到这一点?

4

3 回答 3

22

在标准 SQL 中,没有括号。不是函数。DISTINCT colADISTINCT

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

也添加DISTINCT到子选择中。如果您有许多重复项,则可以加快查询速度。

CTE 可能会更快,具体取决于您的 DBMS。我还演示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 种技术可以排除另一个(或同一个)表中存在键的行:

速度的决定因素将是索引。你需要有索引colA并且colB这个查询要快。

于 2012-01-05T03:07:45.543 回答
6

您可以使用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对于表中的值,通常更快。

于 2012-01-05T03:05:23.550 回答
0

您可以使用EXCEPT有效区分两个SELECT查询的运算符。 EXCEPT DISTINCT将只返回唯一值。Oracle 的MINUS运算符等价于EXCEPT DISTINCT.

于 2012-01-05T03:13:52.283 回答