计算来自发件人的未读邮件

时间:2014-07-14 13:44:58

标签: mysql sql

我正在使用mysql和php构建一个消息传递系统。我已经达到了一个目的,我想选择用户收到的消息,并将从不同用户收到的未读消息计入同一用户。我在下面说明了

table----users
perID | name |
 001  | mum  |
 002  | tok  |
 003  | sat  |

table----messages
msgID |senderID | msgBody |      msgTime       | deleted_by_sender |
 200  | 002     | Hello   | 2014-07-13 19:14:22|  no               |
 201  | 002     | Mate    | 2014-07-13 19:14:29|  no               |
 202  | 003     | hi mum  | 2014-07-13 19:19:12|  no               |
 203  | 003     | How     | 2014-07-13 19:19:52|  no               |

来自父表senderID

users引用
   table----recipients
 recID |msgID |recipientID | msgStatus| deleted_by_recipient|       
 310   | 200  |    001     |  unread  |        no           |
 311   | 201  |    001     |  unread  |        no           |
 312   | 202  |    001     |  read    |        no           |
 313   | 203  |    001     |  read    |        no           |

recipientID引用父表users

我想

1. Get only the current message received by the recipient with recipientID=001
    if it is not deleted by the recipient.

2. count the number of unread messages received from the individual users.

如下所示

senderID | msgID | unread |
   002   |  201  |  2     |
   003   |  203  |  0     |

我的查询按预期工作,但它隐藏了最后一行,因为它在msgStatus列中没有未读取的值, 但我希望即使msgStatus没有价值也会返回所有行。它也应该在一个优化的查询中。

SELECT *,count(msgStatus) As unread  
FROM (
        SELECT
                m.senderID,
                m.msgTime,
                u.perID,
                r.recipientID,
                r.msgID,
                r.msgStatus,
                r.deleted_by_recipient
        FROM 
                messages m
        INNER JOIN 
                users u
            ON 
                m.senderID=u.perID
        INNER JOIN
                recipients r
            ON
                r.msgID=m.msgID

        ORDER BY msgTime DESC
    )h 
WHERE 
    recipientID=12 and 
    deleted_by_recipient ='no' and 
    msgStatus='unread'
GROUP BY perID

感谢您的帮助。

1 个答案:

答案 0 :(得分:3)

您可以使用条件聚合执行所需操作。我们的想法是将条件从where子句移动到select子句:

select senderid,
       max(case when r.deleted_by_recipient = 'no' and r.recipientID = '001' then m.msgID end
          ) as CurrentMsg,
       sum(r.msgStatus = 'unread') as unread
from messages m left outer join
     recipients r
     on  m.msgID = r.msgID
group by senderid;

我不是100%确定这会实现你的逻辑:

  1. 这假设最近的消息是MsgID最大的消息。可以使用substring_index() / group_concat()技巧轻松完成另一个字段。
  2. 无论收件人如何,这都会计算所有未读邮件。通过更改sum()
  3. 中的逻辑,可以轻松解决此问题
  4. 您的示例数据没有重复项(与多个收件人相同的MsgId)。如果可以,您可能需要更改计数的逻辑。再一次,这并不困难,只是不清楚是否需要额外的工作。