MySQL选择连接中没有匹配的地方

时间:2013-08-30 11:11:31

标签: mysql join

我如何在MySQL中执行以下操作:

我有3张桌子:

用户:id

沟通:id,creation_date

user_communication :user_id,communication_id

现在我想选择自给定日期以来没有通信的所有用户。

以下是我现在所拥有的,但我仍然坚持如何得到我上面描述的内容。

SELECT DISTINCT u.id FROM user u
LEFT JOIN user_communication uc ON uc.user_id = u.id
LEFT JOIN communication c ON c.id = uc.communication_id
WHERE c.creation_date < '2013-8-1';

3 个答案:

答案 0 :(得分:3)

where条件正在撤消left join。最初的解决方案是将其移至on子句:

SELECT DISTINCT u.id FROM user u
LEFT JOIN user_communication uc ON uc.user_id = u.id
LEFT JOIN communication c ON c.id = uc.communication_id and c.creation_date < '2013-8-1';

但这不符合你的要求。这将检索所有记录。如果select子句中有创建日期字段,那么在该日期之前有记录时它将为NULL。

自该日期以来没有任何通信,您可以执行“双”否定“查询。查找自该日期以来的记录,并返回不匹配:

SELECT DISTINCT u.id
FROM user u LEFT JOIN
     user_communication uc
     ON uc.user_id = u.id LEFT JOIN
     communication c
     ON c.id = uc.communication_id and c.creation_date >= '2013-08-01'
WHERE c.creation_date is NULL;

编辑:

我明白了。问题比我上面的回答更微妙。每个用户都有多个通信,因此以后都没有。以下查询通过u.id分组然后检查上述联接中没有非NULL值来对此进行测试:

SELECT u.id
FROM user u LEFT JOIN
     user_communication uc
     ON uc.user_id = u.id LEFT JOIN
     communication c
     ON c.id = uc.communication_id and c.creation_date >= '2012-08-01'
group by u.id
having min(c.creation_date is null) = 1;

答案 1 :(得分:1)

SELECT DISTINCT u.id FROM user u
LEFT JOIN user_communication uc ON uc.user_id = u.id
LEFT JOIN (SELECT * FROM communication WHERE creation_date < '2013-8-1') c 
ON c.id = uc.communication_id
WHERE c.id is NULL;

答案 2 :(得分:0)

经过一些研究和帮助,我有以下查询,这似乎有效:

SELECT DISTINCT(u.id)
FROM user u
WHERE (SELECT coalesce(max(c.creation_date), '1900-01-01 00:00:00') last_creation_date
       FROM user inneru 
       LEFT JOIN user_communication uc ON uc.user_id = inneru.id
       LEFT JOIN communication c ON c.id = uc.communication_id
       WHERE inneru.id = u.id) < '2012-08-01'

SQLFiddle:http://sqlfiddle.com/#!2/5dfad/10