我如何在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';
答案 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