11

我在让查询工作时遇到问题,我认为这应该工作。它的形式

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 中。

4

6 回答 6

14

你应该使用不存在:

SELECT DISTINCT a, b, c FROM t1 WHERE NOT EXISTS (SELECT NULL FROM t2 WHERE t1.a = t2.a AND t1.b = t2.b AND t1.c = t2.c)

即使您只检查一个键,使用 NOT IN 也不是最好的方法。原因是,如果您使用 NOT EXISTS,则 DBMS 只需在所需列存在索引的情况下检查索引,而对于 NOT IN,它将必须读取实际数据并创建随后需要检查的完整结果集.

使用 LEFT JOIN 然后检查 NULL 也是一个坏主意,当表很大时它会非常慢,因为查询需要进行整个连接,完全读取两个表,然后丢弃很多。此外,如果列允许 NULL 值,则检查 NULL 将报告误报。

于 2010-02-11T18:30:41.933 回答
4

即使提供了答案,我也很难找出执行此查询的正确方法;然后我找到了我需要的 MySQL 文档参考:

SELECT DISTINCT store_type
FROM stores 
WHERE NOT EXISTS (SELECT * FROM cities_stores WHERE cities_stores.store_type = stores.store_type);

我不得不思考的技巧是使用子查询中第一个查询中对“商店”表的引用。希望这会有所帮助(或对其他人有所帮助,因为这是一个旧线程。)

来自http://dev.mysql.com/doc/refman/5.0/en/exists-and-not-exists-subqueries.html

于 2012-07-26T22:24:28.580 回答
0

据我所知,NOT IN 一次只能用于 1 个字段。并且必须在“WHERE”和“NOT IN”之间指定该字段。

(编辑:)尝试使用不存在:

SELECT a, b, c 
FROM t1 
WHERE NOT EXISTS 
   (SELECT * 
   FROM t2 
   WHERE t1.a = t2.a AND t1.b = t2.b AND t1.c = t2.c)

此外,a、b 和 c 相等的内连接应该给你所有非 DISTINCT 元组,而带有 WHERE IS NULL 子句的 LEFT JOIN 应该给你 DISTINCT 元组,如下查尔斯所述。

于 2010-02-11T18:00:12.360 回答
0

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

于 2010-02-11T18:20:02.003 回答
0

好吧,我要回答我自己的问题,尽管其他人给出了很多很好的建议。

这是我尝试做的正确语法。

SELECT DISTINCT a, b, c FROM t1 WHERE (a,b,c) NOT IN ( SELECT DISTINCT a,b,c FROM t2 )

不能保证它的效率,但我隐含地提出的更广泛的问题是“我如何在 SQL 中表达这种想法”,而不是“我如何获得特定的结果集”。我知道这对每个刺伤的人都不公平,对不起!

于 2010-02-12T03:09:59.600 回答
-1

需要在 WHERE 子句后添加列列表并删除别名。

我用一个类似的表对此进行了测试,它正在工作。

SELECT DISTINCT a, b, c 
FROM t1 WHERE (a,b,c)
NOT IN (SELECT DISTINCT a,b,c FROM t2)

使用 mysql世界数据库:

-- dont include city 1, 2
SELECT DISTINCT id, name FROM city 
WHERE (id, name) 
NOT IN (SELECT id, name FROM city  WHERE ID IN (1,2))
于 2010-02-11T18:36:13.943 回答