2014-11-22 62 views
1

我正在制作消息系统,我需要按发件人和订单按降序对消息进行分组,以便最新消息始终位于最前面。使用GROUP BY和ORDER BY一起检索最新消息

查询

SELECT 
    messages.message_id, 
    messages.message_from, 
    messages.message_to, 
    messages.message_content, 
    messages.message_seen, 
    messages.message_datetime, 
    messages.message_status, 
    profiles.profile_id, 
    profiles.profile_photo, 
    profiles.profile_username, 
    profiles.profile_name 
FROM 
    messages 
INNER JOIN 
    PROFILES 
WHERE 
    profiles.profile_id = messages.message_from 
GROUP BY 
    messages.message_from 
ORDER BY 
    messages.message_id DESC 

这是上面的查询显示的内容。

enter image description here

这是数据库结构的样子 enter image description here

正如你所看到的,MESSAGE_ID按降序排列,但它不是最新的ID。

问:

如何使用GROUP BY和排序一起从上面的数据库查询数据库显示最新的消息,我在想什么?

+0

什么是最新的message_id? – Edrich 2014-11-22 08:22:07

+0

@Edrich请参阅我的更新问题。 – 2014-11-22 08:25:01

回答

3

这是你如何能做到这下面,我没有选择所有的字段,你可以添加需要在选择列表

select 
m.message_id, 
m.message_from, 
m.message_to, 
p.profile_name 
from messages m 
join profiles p on p.profile_id = m.message_from 
left join messages m1 
on m1.message_from = m.message_from 
and m.message_id < m1.message_id 
where 
m1.message_id is null 
order by m.message_id desc 

领域做同样的另一种方式是

select 
m.message_id, 
m.message_from, 
m.message_to, 
p.profile_name 
from messages m 
join profiles p on p.profile_id = m.message_from 
where not exists 
(
    select 1 from messages m1 
    where 
    m1.message_from = m.message_from 
    and m.message_id < m1.message_id 
) 
order by m.message_id desc 

demo

+1

它的工作表示感谢! – 2014-11-22 18:39:08

+0

这是个好主意。不过,我想建议@RedVirus,如果你想获得最新的*最近的*消息,你应该过滤最新的日期,而不一定是最新的ID,但只有在你的上下文中它确实有意义时才会这样做。 – AdamMc331 2014-11-22 19:35:09

+0

@ McAdam331感谢您的建议。 – 2014-11-23 00:38:09

-1

试试这个:

SELECT 
    t2.maxID, 
    messages.message_from, 
    messages.message_to, 
    messages.message_content, 
    messages.message_seen, 
    messages.message_datetime, 
    messages.message_status, 
    profiles.profile_id, 
    profiles.profile_photo, 
    profiles.profile_username, 
    profiles.profile_name 
FROM 
    messages LEFT JOIN PROFILES 
    ON profiles.profile_id = messages.message_from 
    LEFT JOIN 
    (SELECT MAX(message_id) AS maxID,message_from FROM messages GROUP BY message_from) t2 
    ON messages.message_from = t2.message_from 
GROUP BY 
    messages.message_from 
ORDER BY 
    t2.maxID DESC 
+0

不起作用。我相信你的回答和我的问题一样。这也给了我相同的结果。 – 2014-11-22 08:33:42

+0

@RedVirus请参阅我的答案更新。就像这项工作一样。 – Edrich 2014-11-22 09:33:11

+0

当你至少可以对你正在做的修改给出一些解释,而不是像这样删除一段代码时,这会更好。即使它确实解决了他们的问题,也不利于他们向前迈进,或帮助那些偶然发现这个问题的新用户。 – AdamMc331 2014-11-22 16:34:45

0

看起来你真正想在这里做的是从组中获得第一项。这是一个常常以不同方式伪装的常见问题,请参阅此article了解更多信息。

所以,你可以尝试这样的事:

SELECT 
    m.message_id, 
    m.message_from, 
    m.message_to, 
    m.message_content 
    m.message_seen 
    m.message_datetime, 
    m.message_status, 
    p.profile_id, 
    p.profile_photo, 
    p.profile_username, 
    p.profile_name 
FROM message m 
JOIN profiles p ON p.profile_id = m.message_from 
WHERE(
    SELECT COUNT(*) 
    FROM message msg 
    WHERE msg.message_from = m.message_from AND msg.message_datetime <= m.message_datetime 
    ) <= 1 
ORDER BY m.message_id DESC; 

那么在子查询的WHERE子句会做的是拉的最新消息每个message_from ID。我在这里做了一个小小的改动来拉取最新的日期,而不仅仅是最新的message_id值。