Mysql按时间分组数据


Mysql Group Data By Time

更新问题:

这是的数据

   m_to    m_from  m_id    m_time 
        5   5   1   1374769716
        5   5   2   1374771178
        5   5   3   1374771294
        5   5   4   1374771396
        5   5   5   1374771784
        1   5   6   1374772120
        1   5   7   1374773097
        5   1   8   1374773579
        5   1   9   1374774095
        5   1   10  1374774148
        1   5   11  1374777304
        444 5   12  1374779752
        5   444 13  1374780378
        5   5   14  1374781374
        5   5   15  1374832375
        444 5   16  1374837258
        5   444 17  1374837525
        5   444 18  1374838801
        444 5   19  1374838976
        1   5   20  1374842736
        5   5   21  1374842954
        444 5   22  1374843389
        5   5   23  1374843466
        1   5   24  1374843853
        1   5   25  1374848855
        444 5   26  1374848889
        5   5   27  1374848912
        1   5   28  1374849001
        5   5   29  1374849056
        444 5   30  1374850406

第一个coulmn是"m_to",第二个是m_from,第三个是m_id,第四个是m_time

现在我想要的是,我想按m_from分组,按m_time排序。但是,将要添加的新消息应该在顶部,下一行应该在第二行。。。。。。etc

我用过。

SELECT m_from,m_time FROM messages WHERE m_to='5' GROUP BY m_from ORDER BY m_time DESC

但正在恢复类似的东西

444
1
5

因此,它没有正确地对数据进行排序。。

如果您按一列(或多列)进行分组,则必须对所有未分组的列执行某些操作,以便您的查询具有意义。

你必须说出你想对所有分组的值做什么。通常类似于SUM()、AVG()、MIN()、MAX()、GROUP_CONCT()

如果按m_from分组,则无法按m_time排序,因为m_from的所有记录都将分组在一起,对于未分组的值,您将得到任意答案,因为您没有指定如何处理组。

您可能想要使用聚合函数,例如MAX(m_time)来获得m_time的最高值,然后对其进行排序。

我建议做一些类似的事情。

 SELECT MAX(m_id),m_from, MAX(m_time) as latest FROM messages 
    WHERE m_to='XXX' OR m_from='XXX' 
    GROUP BY m_from 
    ORDER BY latest DESC;

这似乎是源于SELECT *GROUP BY的问题。MySQL允许这种情况发生,但它可能会导致一些问题。

MySQL扩展了GROUP BY的使用,因此选择列表可以引用GROUP BY子句中未命名的非聚合列。这意味着前面的查询在MySQL中是合法的。使用此功能可以避免不必要的列排序和分组,从而获得更好的性能。但是,这主要在GROUP BY中未命名的每个非聚合列中的所有值对于每个组都相同时有用服务器可以从每个组中自由选择任何值,因此除非它们相同,否则所选的值是不确定的。此外,从每个组中选择值不会受到添加ORDER by子句的影响。结果集的排序发生在选择了值之后,ORDERBY不会影响服务器在每个组中选择的值。

就获得你想要的数据而言,我认为这对你有用:

SELECT * FROM `messages` ORDER BY m_from ASC, m_time DESC

如果你想先按时间排序,只需将m_from ASC移动到最后的

编辑

考虑到您更新的问题,这应该会将列限制为您想要的内容:

SELECT m_from, m_time  FROM `messages` ORDER BY m_from ASC, m_time DESC

您可以通过执行以下操作来获取与列表顶部显示的最后一条消息相对应的m_from:

SELECT m_from, MAX(m_time) AS m_time
FROM messages 
GROUP BY m_from 
ORDER BY m_time DESC

但如果不知道你想要的输出是什么,很难说。。。

编辑:

希望这个能起作用:

SELECT m_user, MAX(m_id) as m_id, MAX(m_time) AS m_time
FROM (
SELECT m_from AS m_user, MAX(m_id) as m_id, MAX(m_time) AS m_time
 FROM messages 
 WHERE m_to = 5
 GROUP BY m_from
UNION
SELECT m_to AS m_user, MAX(m_id) as m_id, MAX(m_time) AS m_time
 FROM messages 
 WHERE m_from = 5
 GROUP BY m_to
 ) AS result
GROUP BY m_user
ORDER BY m_time DESC