从一列而不是另一列中选择所有值的有效方法
我需要从 colA
返回不在 mytable
的 colB
中的所有值。我正在使用:
SELECT DISTINCT(colA) FROM mytable WHERE colA NOT IN (SELECT colB FROM mytable)
它正在工作,但是查询需要很长时间才能完成。
有没有更有效的方法来做到这一点?
I need to return all values from colA
that are not in colB
from mytable
. I am using:
SELECT DISTINCT(colA) FROM mytable WHERE colA NOT IN (SELECT colB FROM mytable)
It is working however the query is taking an excessively long time to complete.
Is there a more efficient way to do this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
在标准 SQL 中,
DISTINCT colA
中没有括号。DISTINCT
不是一个函数。还将
DISTINCT
添加到子选择中。对于许多重复项,它可以加快查询速度。但是,通常有比NOT IN
更有效的查询技术:速度的决定因素是索引。您需要在
colA
和colB
上建立索引才能加快此查询的速度。CTE 可能会更快,具体取决于您的 DBMS。我还演示了 LEFT JOIN 作为排除 valB 中的值的替代方法,以及使用 GROUP BY 获取不同值的替代方法:
或者,简化进一步,并使用普通子查询(可能是最快的):
In standard SQL there are no parentheses in
DISTINCT colA
.DISTINCT
is not a function.Added
DISTINCT
to the sub-select as well. For many duplicates it can speed up the query. But, typically, there are more efficient query techniques thanNOT IN
for this:The deciding factor for speed will be indexes. You need indexes on
colA
andcolB
for this query to be fast.A CTE might be faster, depending on your DBMS. I additionally demonstrate
LEFT JOIN
as alternative to exclude the values invalB
, and an alternative way to get distinct values withGROUP BY
:Or, simplified further, and with a plain subquery (probably fastest):
您可以使用
exists
:exists
执行半连接来快速匹配值。not in
完成整个结果集,然后对其执行or
操作。对于表中的值,exists
通常更快。You can use
exists
:exists
does a semi-join to quickly match the values.not in
completes the entire result set and then does anor
on it.exists
is typically faster for values in tables.您可以使用
EXCEPT
运算符,该运算符有效比较两个SELECT
查询。EXCEPT DISTINCT
将仅返回唯一值。 Oracle 的MINUS
运算符是相当于EXCEPT DISTINCT
。You can use the
EXCEPT
operator which effectively diffs twoSELECT
queries.EXCEPT DISTINCT
will return only unique values. Oracle'sMINUS
operator is equivalent toEXCEPT DISTINCT
.