我正在尝试通过一个优雅的SQL查询从我的私人消息表中获取对话。这是我的表格的简化版本:
假设我想要找回所有詹姆斯的谈话。以绿色突出显示的行是我希望他在收件箱中显示的行。换句话说,我想选择james收到的最新消息,按发件人分组。我尝试过以下查询:
SELECT *
FROM "messages"
WHERE To = "James"
ORDER BY Id DESC
GROUP BY `From`
但MySQL将这些行返回给我:
那我怎么能解决这个问题?
谢谢!
编辑:我不应该使用“发件人”作为字段名称,我现在不会更改它以避免违反答案但是抱歉。
答案 0 :(得分:4)
SELECT M.Id,
M.`From`,
M.`To`,
M.message
FROM messages M
INNER JOIN
(SELECT `from`, max(Id) as maxId
FROM messages
WHERE `to` = "James"
GROUP BY `from`)T
ON M.Id = T.maxId
你说你想要'詹姆斯'收到的消息,但你比较from = 'James'
这是一个错误吗?
编辑:@Lotharyx想知道是否有办法在没有子查询的情况下完成它,所以这是一种方法。请参阅此sqlFiddle
中的第二个查询SELECT IF(@prevFrom IS NULL OR @prevFrom != M.`From`,@row:=1,@row:=@row +1) as row,
@prevFrom:=M.`From`,
M.id, M.`From`, M.`To`, M.message
FROM messages M
WHERE `to` = 'James'
HAVING row = 1
ORDER BY M.`From`, M.Id DESC;
答案 1 :(得分:1)
From是一个保留字,用反引号括起来。
答案 2 :(得分:0)
您不需要GROUP BY子句,因为您没有使用聚合函数。删除它,你应该得到你想要的结果。其他人建议使用自连接和子查询的查询,这是不必要的复杂。
SELECT * FROM `messages` WHERE `To` = 'James' ORDER BY `Id` DESC LIMIT 5
这将给你詹姆斯最近的5条消息。根据需要更改LIMIT参数。
请注意,LIMIT
是特定于mysql的扩展,但是您使用mysql标记,因此我认为这是您正在使用的引擎。
答案 3 :(得分:0)
应该是这样的
SELECT * FROM messages WHERE `From` = 'James' ORDER BY Id DESC
答案 4 :(得分:0)
这个问题已经过时了,但如果其他人有类似疑问,这就是我的解决方案:
假设詹姆斯有ID 1(我使用ID但可以随意更换1) “詹姆斯”是用户名,身份证等。)
SELECT IF(`from` = 1, `to`, `from`) AS `friend_id`, `message`, `created_at`
FROM `messages`
WHERE `from` = 1 OR `to` = 1
GROUP BY friend_id
ORDER BY `created_at` DESC
我不确定这是否是最好的解决方案,但它会获取正确的消息。诀窍是使用IF来获取friend_id(它可以在“from”或“to”列中