mysql 查询问题 关于 not in

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mysql 查询问题 关于 not in相关的知识,希望对你有一定的参考价值。

mysql> SELECT 10050001 NOT IN (
-> SELECT `CampusID`
-> FROM `USERS`
-> );
+----------------------------------------------------+
| 10050001 NOT IN (
SELECT `CampusID`
FROM `USERS`
) |
+----------------------------------------------------+
| NULL |
+----------------------------------------------------+
为什么会出现这样的结果呢?

参考技术A MySQL中NOT IN语句对NULL值的处理2007-07-23 16:01mysql> SELECT COUNT(name) FROM CVE WHERE name NOT IN ('CVE-1999-0001', 'CVE-1999-0002');
+-------------+
| count(name) |
+-------------+
| 17629 |
+-------------+
1 row in set (0.02 sec)

mysql> SELECT COUNT(name) FROM CVE WHERE name NOT IN ('CVE-1999-0001', 'CVE-1999-0002', NULL);
+-------------+
| count(name) |
+-------------+
| 0 |
+-------------+
1 row in set (0.01 sec)

当在子查询中出现NULL的时候,结果就一定是0了。查了一下手册,确实有这样的说法。所以最后实际采用了这样的查询:
SELECT COUNT(DISTINCT name)
FROM CVE
WHERE name NOT IN (SELECT cveID FROM cve_sig WHERE cveID IS NOT NULL)

顺便提一下MySQL中正则表达式匹配的简单使用:
SELECT COUNT(alarmID)
FROM Alarm
WHERE (CVE NOT RLIKE '^CVE-[0-9]4-[0-9]4$' OR CVE IS NULL)
当然,RLIKE也可以写作REGEXP,我个人倾向于使用RLIKE,因为拼写接近LIKE,可以见名知义。本回答被提问者采纳

MySql如何将LEFT JOIN查询与NOT IN查询结合起来

【中文标题】MySql如何将LEFT JOIN查询与NOT IN查询结合起来【英文标题】:MySql how to combine LEFT JOIN query with NOT IN query 【发布时间】:2015-11-12 10:14:09 【问题描述】:

我需要将LEFT JOIN 查询与NOT IN 查询结合起来,并且必须从这些查询中获取结果值。分别使用这两个查询时,我得到了正确的结果。

我有两张桌子可能是useranswer

user

user_id 
1
2
3
4
5

answer

user_id     date 
1           2015-10-15 21:23:14
2           2015-10-15 20:23:14
3           2015-11-11 16:23:14

LEFT JOIN查询:

SELECT user.user_id
FROM user 
LEFT JOIN answer 
  ON user.user_id = answer.user_id 
WHERE DATEDIFF(NOW(),answer.date) > 5

此查询返回结果user_id 1,2。

NOT IN查询:

SELECT user.user_id 
FROM user 
WHERE user.user_id NOT IN (SELECT answer.user_id FROM answer)

此查询返回结果user_ids 4, 5。

我需要将这两个查询组合成一个查询,所以我尝试使用以下两个查询:

 SELECT user.user_id 
 FROM user 
 LEFT JOIN answer 
   ON user.user_id = answer.user_id 
 WHERE (DATEDIFF(NOW(),answer.date) > 5 
   AND user.user_id NOT IN (SELECT answer.user_id FROM answer))

 SELECT user.user_id 
 FROM user 
 LEFT JOIN answer 
   ON user.user_id = answer.user_id 
 WHERE user.user_id NOT IN (SELECT answer.user_id FROM answer) 
   AND DATEDIFF(NOW(),answer.date) > 5 

但是这些返回空user_id

编辑

预期结果应该包含1,2,4,5的值

【问题讨论】:

您希望看到什么输出? 不应该是WHERE DATEDIFF(NOW(),answer.date) < 5 吗? 【参考方案1】:

如果您的意思是将 2 个选择组合在一起 试试 Union All / Union

SELECT * FROM 
(
SELECT [WITH YOUR LEFT JOIN STATEMENT]
UNION 
SELECT [WITH YOUR NOT IN STATEMENT]
) ResultTABLE

【讨论】:

这就是我们过去在 SQL92 引入 LEFT JOINS 之前的模拟方式。【参考方案2】:

如果您在 WHERE 子句中引用答案表,answer.date 将被限制为非 NULL 值,从而使 LEFT JOIN 的行为类似于常规连接。将条件移动到ON 条件以检索所有用户,以及可能answers中的匹配行:

 SELECT user.user_id
 FROM user u
 LEFT JOIN answer a ON u.user_id = a.user_id
                    AND DATEDIFF(NOW(),a.date) < 5
    ;

编辑:在编辑问题后,似乎 OP 希望加入不存在答案的记录或 answer.date 太旧/太年轻:

 SELECT user.user_id
 FROM user u
 LEFT JOIN answer a ON u.user_id = a.user_id
 WHERE a.date IS NULL               -- no answer record
    OR DATEDIFF(NOW(),a.date) > 5   -- too old answer record
    ;

最终版本:由于 OP 想要找到没有(最近)答案的用户,查询可以简化为:

SELECT user.user_id
FROM user u
WHERE NOT EXISTS (
    SELECT * FROM answer a
    WHERE a.user_id = u.user_id
    AND DATEDIFF(NOW(), a.date) <= 5
    );

【讨论】:

即像这样在 WHERE 子句中使用答案表的条件,LEFT JOIN 作为常规 INNER JOIN 执行。 没错! (我会补充) @joop 你编辑的答案返回1,2,4,5 但我需要3,4,5 对不起,实际上我的left join 查询返回了1,2 的值,但我认为3 一个人。 那是因为greater than 符号被翻转了(请参阅我对问题的评论)我会为您修复它。

以上是关于mysql 查询问题 关于 not in的主要内容,如果未能解决你的问题,请参考以下文章

优化 MySQL NOT IN( 查询

使用“NOT IN”优化 MySQL 查询

MySQL 查询不适用于 NOT IN

MySQL:如何查询复合主键?具体来说,一个 NOT IN 查询?

MySql如何将LEFT JOIN查询与NOT IN查询结合起来

MYSQL NOT IN 子选择查询