mysql SELECT NOT IN () -- 不相交集?
我在查询工作时遇到问题,我认为这应该有效。它的形式是
SELECT DISTINCT a, b, c FROM t1 WHERE NOT IN ( SELECT DISTINCT a,b,c FROM t2 ) AS alias
但是 mysql 在“IN (”开始的地方被阻塞。mysql 支持这种语法吗?如果不支持,我怎样才能得到这些结果?我想在表 1 中找到 (a,b,c) 的不同元组表2中不存在。
I'm having a problem getting a query to work, which I think should work. It's in the form
SELECT DISTINCT a, b, c FROM t1 WHERE NOT IN ( SELECT DISTINCT a,b,c FROM t2 ) AS alias
But mysql chokes where "IN (" starts. Does mysql support this syntax? If not, how can I go about getting these results? I want to find distinct tuples of (a,b,c) in table 1 that don't exist in table 2.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
您应该使用 not contains:
即使您只检查一个键,使用 NOT IN 也不是执行此操作的最佳方法。原因是,如果您使用 NOT EXISTS,DBMS 只需检查所需列是否存在索引,而对于 NOT IN,则必须读取实际数据并创建随后需要检查的完整结果集。
使用 LEFT JOIN 然后检查 NULL 也是一个坏主意,当表很大时,它会非常慢,因为查询需要进行整个连接,完全读取两个表,然后丢弃大量表。此外,如果列允许 NULL 值,检查 NULL 将会报告误报。
You should use not exists:
Using NOT IN is not the best method to do this, even if you check only one key. The reason is that if you use NOT EXISTS the DBMS will only have to check indices if indices exist for the needed columns, where as for NOT IN it will have to read the actual data and create a full result set that subsequently needs to be checked.
Using a LEFT JOIN and then checking for NULL is also a bad idea, it will be painfully slow when the tables are big since the query needs to make the whole join, reading both tables fully and subsequently throw away a lot of it. Also, if the columns allow for NULL values checking for NULL will report false positives.
即使提供了答案,我也无法找出执行此查询的正确方法;然后我找到了我需要的 MySQL 文档参考:
我必须绞尽脑汁的技巧是使用子查询内第一个查询中对“stores”表的引用。希望这会有所帮助(或帮助其他人,因为这是一个旧线程。)
来自 http://dev.mysql.com/doc/refman/5.0/en/exists-and-not-exists-subqueries.html
I had trouble figuring out the right way to execute this query, even with the answers provided; then I found the MySQL documentation reference I needed:
The trick I had to wrap my brain around was using the reference to the 'stores' table from the first query inside the subquery. Hope this helps (or helps others, since this is an old thread.)
From http://dev.mysql.com/doc/refman/5.0/en/exists-and-not-exists-subqueries.html
SELECT DISTINCT t1.* FROM t1 LEFT JOIN t2 ON (t1.a = t2.a AND t1.b = t2.b AND t1.c = t2.c) WHERE t2.a 为 NULL
SELECT DISTINCT t1.* FROM t1 LEFT JOIN t2 ON (t1.a = t2.a AND t1.b = t2.b AND t1.c = t2.c) WHERE t2.a IS NULL
据我所知,NOT IN 一次只能用于 1 个字段。并且该字段必须在“WHERE”和“NOT IN”之间指定。
(编辑:)
尝试使用 NOT EXISTS:
此外,a、b 和 c 相等的内部联接应该为您提供所有非 DISTINCT 元组,而带有 WHERE IS NULL 子句的 LEFT JOIN 应该为您提供 DISTINCT 元组,正如 Charles 提到的以下。
As far as I know, NOT IN can only be used for 1 field at a time. And the field has to be specified in between "WHERE" and "NOT IN".
(Edit:)
Try using a NOT EXISTS:
In addition, an inner join on a, b, and c being equal should give you all non-DISTINCT tuples, while a LEFT JOIN with a WHERE IS NULL clause should give you the DISTINCT ones, as Charles mentioned below.
好吧,尽管其他人给出了很多很好的建议,我还是要回答我自己的问题。
这是我想要做的事情的正确语法。
不能保证它的效率,但我隐含提出的更广泛的问题是“如何用 SQL 表达这个想法”,而不是“如何获得特定的结果集”。我知道这对所有被刺伤的人不公平,对不起!
Well, I'm going to answer my own question, in spite of all the great advice others gave.
Here's the proper syntax for what I was trying to do.
Can't vouch for the efficiency of it, but the broader questions I was implicitly putting was "How do I express this thought in SQL", not "How do I get a particular result set". I know that's unfair to everyone who took a stab, sorry!
需要在 WHERE 子句后添加列列表并删除别名。
我用类似的表对此进行了测试,它正在工作。
使用 mysql world 数据库:
Need to add a column list after the WHERE clause and REMOVE the alias.
I tested this with a similar table and it is working.
Using the mysql world db: