【问题标题】:MySQL Find records in one table that has no value of a column in another tableMySQL在一个表中查找另一个表中没有列值的记录
【发布时间】:2025-12-17 06:45:01
【问题描述】:

我有 table1,包含列(简化):

+-------------------------+
| id | user_id | username |
+----+---------+----------+
|  1 |     123 | peter    |
|  2 |     234 | john     |
+-------------------------+

和表 2,包含列(简化):

+----------------------------------+
| id | user_id | checklist_item_id |
+----+---------+-------------------+
|  1 |     123 |               110 |
|  2 |     123 |               111 |
|  3 |     123 |               112 |
|  4 |     234 |               110 |
|  5 |     234 |               112 |
+----------------------------------+

如上所示,table1 中 user_id 的每个条目,对于该 user_id 具有多个 checklist_item_id 的多个条目。

我有兴趣只返回在第二个表中没有 checklist_item_id = 111 条目的记录。查询必须只返回:

+---------+
| user_id |
+---------+
|     234 |
+---------+

作为 user_id 为 123 的用户,在表 2 中有一个 checklist_item_id 为 111 的条目。

【问题讨论】:

  • 使用not exists

标签: mysql


【解决方案1】:

可以使用子查询,例如:

SELECT *
FROM table1
WHERE user_id NOT IN
    (SELECT user_id
     FROM table2
     WHERE checklist_item_id = 111)

【讨论】:

  • 感谢您的回复。它也有效,但第一个答案的全面性被接受了。
【解决方案2】:

使用相关子查询

select t1.* from  table1 t1 where t1.user_id not in
( select user_id from table2 t2
   where t2.user_id=t1.user_id
   and checklist_item_id=111
)

或者使用not exist,比不使用效率高

select t1.* from table1 t1 where not exists
    ( select 1 from table2 t2  where t2.user_id=t1.user_id and 
    checklist_item_id=111
    )    

DEMO in Fiddle

id  userid  itemid
4   234     110
5   234     112

如果你只需要一个 id 那么它会是

select distinct t1.userid from  t1 where not exists
    ( select 1 from t1 t2  where t2.userid=t1.userid and 
    itemid=111
    )    

输出

userid
  234

Demo

【讨论】:

  • 谢谢。我只对 user_id 感兴趣,所以我会按 user_id 分组。对吗?
  • @KobusMyburgh dbfiddle.uk/… 勾选仅返回用户 ID
  • 抱歉,是的,我看到之后还有第二个演示。谢谢。已接受您的回答。
【解决方案3】:

最简单有效的方法是使用LEFT JOIN,并过滤掉那些没有checklist_item_id = 111匹配记录的行

SELECT DISTINCT t1.user_id 
FROM table1 AS t1 
LEFT JOIN table2 AS t2 ON t2.user_id = t1.user_id AND 
                          t2.checklist_item_id = 111 
WHERE t2.user_id IS NULL 

【讨论】:

  • 感谢您的回复。它也有效,但第一个答案的全面性被接受了。
  • @KobusMyburgh 不用担心接受的答案。但是出于您的实际目的,如果您可以使用基于联接的解决方案,则应避免使用子查询。这将大大提高效率
最近更新 更多