2017-08-16 88 views
1

我有我的网站用户(总是在两个用户)之间的联系机制。用户A(发送者)可以发送消息以基于两个规则的用户B(接收器):如何在特定行之后对行进行计数?

  1. 用户A可以发送2个消息极力用户B和他必须接收来自用户B的至少一个消息是能够发送另一个2.

  2. 用户A可以在每天的时间段内向每个人发送4条消息,而不是更多。

这里是我的表结构:

-- contact 
+----+-----------+------------+--------------------------+------------+ 
| id | sender_id | receive_id |   message   | date_time | 
+----+-----------+------------+--------------------------+------------+ 
| 1 | 123  | 456  | Hi, how are you?   | 1492431111 | 
| 2 | 123  | 789  | How are you doing?  | 1492431112 | 
| 3 | 456  | 789  | Why would you say that? | 1492431113 | 
| 4 | 123  | 456  | Why don't you answer? | 1492431114 | 
| 5 | 789  | 456  | Because the sky is high | 1492431115 | 
| 6 | 123  | 789  | Hello?     | 1492431116 | 
+----+-----------+------------+--------------------------+------------+ 

这里是我当前的查询:

INSERT INTO contact(sender_id, receive_id, message, date_time) 
SELECT ?, ?, ?, unix_timestamp() 
FROM dual 
WHERE NOT EXISTS(
    SELECT count(*) AS num_day, 
    FROM contact 
    WHERE user_id = ? 
     AND date_time > unix_timestamp(DATE_SUB(now(), INTERVAL 1 day)) 
    HAVING num_day > 4 
) 

正如你所看到的,只有第二条规则是我的查询实现。我怎样才能实现查询的第一条规则?

+0

一般来说,如果您在*行之后提及行*,您必须让它们按某列排序。因此,您可以计算该列中的值大于(或小于)该列中该列的值的相关行。 –

+0

@JiriTousek你的意思是我需要添加一列?我确定。如果你认为这是解决方案,请写一个答案 – stack

+0

不,我的意思是说,在考虑“之后”时,你可能按行列排序。因此,您可以比较此列中的值以确定行是“之前”还是“之后”,并且只在“之后”计算行。 –

回答

0

查询,找出从“A”到“B”的消息的数量,因为他们的最后回复:

SELECT count(*) 
FROM contact 
WHERE sender_id = 'A' 
    AND receive_id = 'B' 
    AND date_time > (
    SELECT max(date_time) 
    FROM contact 
    WHERE sender_id = 'B' 
     AND receive_id = 'A' 
    ) 

注意这将可能无法正常工作,如果没有从“B”至“A”的消息尚未 - 你必须修改查询来解决这个问题。

+0

如果没有最大日期(因此最大返回null),请在最大周围添加COALESCE,即1900年1月的日期(因此最大返回空值) –

+0

^和我认为在这里需要使用'order by'子句来处理'date_time'列。 – stack

+0

@CaiusJard谢谢,我不是很熟悉Mysql。 ''ALL'会同样好吗? –

0

我不确定在数据库中实现这个逻辑是一个非常好的主意 - 你似乎在寻找一个只会插入消息的查询如果他们还没有联系过两次以上的消息,的逻辑在前端应用程序中会更好。为此,你会与一对夫妇查询的更好:

Select count(*) from contact where sender_id = A and date_time > unix_timestamp(curdate()) 

,否认它是否> = 4

运行JiriTousek的查询发送消息,并拒绝发送,如果它是> = 2

通过拒绝发送,我的意思是改变前端,所以消息传递是不可能的,所以他们不会浪费他们的生命输入永远不会发送的消息。在插入时做这个阻塞有点太迟了

相关问题