这段代码:
SELECT m.message,
MAX(m.time) AS time,
m.sender,
m.receiver,
m.contact,
u.ufirstname
FROM( (SELECT message,
receiver_uid AS receiver,
sender_uid AS sender,
time,
receiver_uid AS contact
FROM messages
WHERE sender_uid = '$me' )
UNION
(SELECT message,
receiver_uid AS receiver,
sender_uid AS sender,
time,
sender_uid AS contact
FROM messages
WHERE receiver_uid = '$me' ) ) AS m,
users AS u
WHERE m.contact = u.uid
GROUP BY m.contact
ORDER BY time DESC;
我的问题是这一部分应该选择对话的最新消息。 这是数据库的格式:
Sender_uid | receiver_uid | message | time («What format should this be?)
第一部分检索“$me”(=登录用户的用户ID)参与的所有消息。因此,所有消息,无论“$me”正在发送还是接收。 第二部分应为每个“对话”选择最近时间(最大值)(=联系人 ID,联系人是接收者还是发送者)
它没有收到最新消息。它确实为您提供了对话中的一条消息。
重要提示(?):我认为脚本正在做的是检索最新的消息,其中“$me”是发件人。
我希望它收集最后一条消息,无论 $me 是接收者还是发送者。
最佳答案
请停止滥用 MySQL 混合聚合和非聚合。虽然 MySQL 允许这样做,但每列来自哪些记录是不可预测的,它们甚至不必来自同一条记录(同步)
SELECT m2.message,
m2.time AS time,
m2.sender,
m2.receiver,
m.contact,
u.ufirstname
FROM (
SELECT
case when sender_uid = '$me' then receiver_uid else sender_uid end Contact,
max(time) maxtime
FROM messages
WHERE sender_uid = '$me' or receiver_uid = '$me'
group by case when sender_uid = '$me' then receiver_uid else sender_uid end
) AS m
INNER JOIN messages m2 on m.maxtime = m2.time
and ((m2.sender_uid = '$me' and m2.receiver_uid = m.Contact)
or
(m2.receiver_uid = '$me' and m2.sender_uid = m.Contact))
INNER JOIN users AS u on m.contact = u.uid
ORDER BY time DESC;
@updated 查询 - 比看起来更复杂。
- “联系人”是对话的另一方。
- 内部 OR 仅用于遍历表一次。
- 内层CASE语句用于获取对方的ID。 如果“$me”与发送者匹配,则接收者成为“联系人” 否则发件人就是“联系人”
- 与 m2 的连接使用 3 个属性 - me、contact(任一方向)和 maxtime 此连接使用内部查询 (maxTime) 中的键来检索 表中的完整记录
- 与用户进行最终连接以获取联系人的名字
关于SQL MAX(m.time) 不选择最高值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4727906/