MySQL获取在24小时内收到评论且未得到回复的用户

时间:2014-08-25 17:30:58

标签: mysql

我有一个网络应用,用户可以互相发送评论。

我需要找到收到评论且未在24小时内向任何用户发送评论的用户。

相关的表/字段是:user.id,comment.recipient,comment.sender,comment.date

这是我到目前为止所做的:

SELECT u.* FROM user AS u 
INNER JOIN comment AS c1 ON u.id = c1.recipient
INNER JOIN comment AS c2 ON u.id = c2.sender
WHERE c2.date >= ( CURDATE() - INTERVAL 1 DAY )
AND c2.recipient = c1.sender
AND c1.date < c2.date
GROUP BY u.id

更新

这要归功于我,感谢Frazz:

SELECT u.id,u.firstName,u.lastName
FROM user AS u 
JOIN comment AS c1 ON u.id = c1.recipient
WHERE DATE(c1.date) BETWEEN ( CURDATE() - INTERVAL 47 HOUR ) AND ( CURDATE() - INTERVAL 24 HOUR )
AND NOT EXISTS (
SELECT c2.sender
FROM comment AS c2
WHERE c2.date > c1.date
AND c2.sender = u.id
)
GROUP BY u.id

1 个答案:

答案 0 :(得分:1)

第一眼看,我说你正在寻找这样的东西:

SELECT u.*
FROM user    AS u 
JOIN comment AS c1 ON u.id = c1.recipient
WHERE c1.date >= ( CURDATE() - INTERVAL 1 DAY )
AND NOT EXISTS (
  SELECT sender
  FROM comment AS c2
  WHERE c2.date > c1.date
  AND   c2.sender = u.id
  AND   c2.recipient = c1.sender)

您还可以使用LEFT JOIN获得相同的结果,在c2.sender列中测试NULL,如下所示:

SELECT u.*
FROM      user    AS u 
JOIN      comment AS c1 ON u.id = c1.recipient
LEFT JOIN comment AS c2 ON u.id = c2.sender AND c1.sender = c2.recipient
WHERE c1.date >= ( CURDATE() - INTERVAL 1 DAY )
AND   c2.date > c1.date
AND   c2.sender IS NULL

我更喜欢第一个。 LEFT JOIN可能很昂贵,只有在实际需要时才能使用。这不是这种情况,因为您实际上在寻找不匹配的行。

我拿出了GROUP BY,因为我不确定你想从中获得什么。对具有SELECT *的查询进行分组是有风险的......您永远无法确定引擎将保留哪一行以及哪些行将被丢弃。如果您希望每个用户只有一行,那么您最好说明用于选择一个用户的逻辑,以防同一个用户未响应来自不同其他用户的多个评论。

根据您添加的评论,如果您只需要用户ID,则可以简化第一个查询:

SELECT DISTINCT c1.recipient
FROM comment AS c1
WHERE c1.date >= ( CURDATE() - INTERVAL 1 DAY )
AND NOT EXISTS (
  SELECT sender
  FROM comment AS c2
  WHERE c2.date > c1.date
  AND   c2.sender = c1.recipient
  AND   c2.recipient = c1.sender)

在这种情况下,DISTINCT将照顾必须回复他们收到的多条评论的用户。