共有五个数据表:
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解释了theUser
,theGroup
和Membership
之间的关系。现在,我想要提取对话(gpMsge
和idMsge
)并按照该对话中新设置消息的顺序显示相应发件人的名称(theUser
和theGroup
) 。实际上,业务逻辑与Whatsapp
完全相同。在第一部分中,发件人姓名(如果对话是p2p,则为个人用户名,如果是在组内,则为组名),按照该对话中最新消息的时间顺序显示。在每个发件人名称下方,该对话中应该有五条最新消息。在第二部分中,显示所有没有对话的组(无需在此部分中指定顺序)。
现在我遇到的困难是对话的顺序,因为gpMsge
和idMsge
是孤立的。如何对每个表中的time
值进行排序,并在表格中获取theUser
和theGroup
的名称?提前谢谢!
答案 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;
如果要选择一个特定的发件人或收件人,则必须添加一个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;
获取具有特定用户的所有组作为成员并且尚未收到任何消息:
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);