在连接中独立地向两个表添加约束

时间:2015-05-04 20:31:33

标签: mysql constraints

我正在尝试从两个不同的表创建一个SELECT语句,我用它来发送消息,我不想在加入后1周向某人发送消息,但是如果我已经发送了它们我希望在发送下一封邮件之前等待10天。

以下是我所拥有的:

SELECT c.*, g.resToMeeting, g.replied, g.conlevel, g.coffee, g.lastMessageSent 
FROM connections c
INNER JOIN groupmembers g
ON c.Id=g.Id 
AND g.groupN=244 # this decides the client I'm pulling for...(or group they own)
AND g.client=c.client
AND g.conlevel=1
AND (datediff(curdate(), g.lastMessageSent) > 10 OR datediff(curdate(), c.dateConnected) > 7)
AND c.validated=1 
AND c.process_rank=0 
ORDER BY c.dateAdded ASC
LIMIT 0, 200

我遇到的麻烦在于它显示了在上周没有加入的人,或者在过去10天内没有收到消息的人。它似乎无法正常工作:

我收到的记录是lastMessageSent为2015-04-29,(10天前不是),但dateConnected是2015-04-15,超过7天。我怎样才能同时执行这两条规则"不是或者,有时在lastMessageSent或dateConnected中没有数据,那应该没问题。

3 个答案:

答案 0 :(得分:1)

一般来说,ON子句应该说明表是如何连接的。

之后,您有一个WHERE子句,列出了任何表所需的过滤。

我怀疑你应该有:

... INNER JOIN groupmembers g
  ON c.Id=g.Id
WHERE g.groupN=244 ...

修改

我想你想要这个,而不是XOR

AND g.lastMessageSent < NOW() - INTERVAL 10 DAY -- Avoid frequent spamming
AND c.dateConnected < NOW() - INTERVAL 7 DAY -- Wait a while before first message

请注意,我重新进行了比较 - 将列放在一边并将常量放在另一边总是好的。这允许使用INDEX的可能性;隐藏DATEDIFF()内的列不会。

CURDATE从今天早晨的午夜算起; NOW从这一秒开始算回。 (你选择;我只是建议另一种选择。)

警告:如果&#34;没有发送任何消息&#34;在NULL中存储为g.lastMessageSent,然后上面的内容为false。所以也许你需要

AND ( g.lastMessageSent IS NULL
   OR g.lastMessageSent < CURDATE() - INTERVAL 10 DAY ) -- Avoid frequent spamming
AND c.dateConnected < CURDATE() - INTERVAL 7 DAY -- Wait a while before first message

&#34;在我的理解中,要么......或者#34;是OR。 &#34;要么是,要么不是两个&#34;是XOR

答案 1 :(得分:0)

&#34;无论是&#34;是异或。即(A而不是B)或(不是A和B),所以改变这个条件

AND (datediff(curdate(), g.lastMessageSent) > 10 OR datediff(curdate(), c.dateConnected) > 7)

AND ( ((datediff(curdate(), g.lastMessageSent) > 10 AND datediff(curdate(), c.dateConnected) < 7)) OR ((datediff(curdate(), g.lastMessageSent) < 10 AND datediff(curdate(), c.dateConnected) > 7)) )

请注意,我没有使用NOT,而是颠倒了条件。

修改

由于MySQL具有XOR运算符,因此可以将该行重写为:

AND (datediff(curdate(), g.lastMessageSent) > 10 XOR datediff(curdate(), c.dateConnected) > 7)

答案 2 :(得分:0)

为什么你可以改变:

AND (datediff(curdate(), g.lastMessageSent) > 10 OR datediff(curdate(),     c.dateConnected) > 7)

为:

AND datediff(curdate(), g.lastMessageSent) > 10 
AND datediff(curdate(), c.dateConnected) > 7