如何使用Mysql以特定顺序从两个不同的表中选择消息?

时间:2016-05-19 11:01:20

标签: mysql

共有五个数据表:

theUser (*id*, name)
theGroup (*id*, name)
Membership (*group_id*, *user_id*)
gpMsge (*id*, sender, receiver, content, time)  # message within group
idMsge (*id*, sender, receiver, content, time)  # message between user and user

question解释了theUsertheGroupMembership之间的关系。现在,我想要提取对话(gpMsgeidMsge)并按照该对话中新设置消息的顺序显示相应发件人的名称(theUsertheGroup) 。实际上,业务逻辑与Whatsapp完全相同。在第一部分中,发件人姓名(如果对话是p2p,则为个人用户名,如果是在组内,则为组名),按照该对话中最新消息的时间顺序显示。在每个发件人名称下方,该对话中应该有五条最新消息。在第二部分中,显示所有没有对话的组(无需在此部分中指定顺序)。

现在我遇到的困难是对话的顺序,因为gpMsgeidMsge是孤立的。如何对每个表中的time值进行排序,并在表格中获取theUsertheGroup的名称?提前谢谢!

1 个答案:

答案 0 :(得分:2)

您可以使用“UNION”,以便比较两个不同表格之间的时间

此查询将列出两个表中的最后5个会话。

SELECT id,sender,receiver,content,time
FROM gpMsge
UNION
SELECT id,sender,receiver,content,time
FROM idMsge
ORDER BY time DESC 
LIMIT 5

更新

完整查询将是这样的::

 SELECT US.name AS sender,GR.name AS receiver,content,time 
     FROM gpMsge AS GM 
     LEFT JOIN theUser AS US ON GM.sender=US.id 
     LEFT JOIN theGroup AS GR ON GM.receiver=GR.id 
 UNION 
 SELECT US.name AS sender,UR.name AS receiver,content,time 
    FROM idMsge AS UM 
    LEFT JOIN theUser AS US ON UM.sender=US.id 
    LEFT JOIN theUser AS UR ON UM.receiver=UR.id 
 ORDER BY time DESC
 LIMIT 5;

see demo

如果要选择一个特定的发件人或收件人,则必须添加一个WHERE子句:

此查询将选择发送给ID号为2的接收者的所有会话:向该用户发送直接消息或发送给以该用户为成员的群组的消息。

对于您的上一个问题,您可以添加一个额外的字段来检查消息是否是从组内外的用户发送的,这可能是某些文本或int ...

SELECT  US.name AS sender,GR.name AS receiver,content,
        "This is a message in a group" AS sent_from,time 
    FROM gpMsge AS GM 
    LEFT JOIN theUser AS US ON GM.sender=US.id 
    LEFT JOIN theGroup AS GR ON GM.receiver=GR.id 
    WHERE receiver IN (
           SELECT group_id FROM  Membership WHERE user_id=2
    )

UNION 

SELECT  US.name AS sender,UR.name AS receiver,content,
        "This is a message from a user" AS sent_from, time
   FROM idMsge AS UM 
   LEFT JOIN theUser AS US ON UM.sender=US.id 
   LEFT JOIN theUser AS UR ON UM.receiver=UR.id 
   WHERE receiver=2

ORDER BY time DESC  
LIMIT 5;

DEMO

获取具有特定用户的所有组作为成员并且尚未收到任何消息:

SELECT id,name 
FROM  Membership AS M 
JOIN theGroup AS G ON M.group_id=G.id 
WHERE user_id=2 
AND group_id NOT IN (SELECT receiver FROM gpMsge);

SEE DEMO