zoukankan      html  css  js  c++  java
  • mysql关于group by分组取创建时间最新/某个值最大的记录 的讨论

    1.数据表test的结构和数据如下:

         

        

     问题:

    1.我只想获取某个项目(project_id=1)的最新评论。(create_time越大,说明评论越新)

       按道理可以这样做:

       1)排好序  SELECT * FROM `test` where project_id = 1 order by project_id,create_time desc;

      

       2)然后在上面排好序的基础上分组  

          select * from (SELECT * FROM `test` where project_id = 1 order by project_id,create_time desc) t GROUP BY project_id;

          

          结果是看似正确的,实则是错误的。

      如:修改id为1的create_time,然后再排序:

      

           可以看到id为1的数组被排到最后。再对该结果进行分组:

           select * from (SELECT * FROM `test` where project_id = 1 order by project_id,create_time desc) t GROUP BY project_id;

           

           从结果可以看到,我们需要的数据是id为4的数据,但分组后却拿到了id为1的数据,这显然是错误的。

          如果不限定project_id,对整个数据表进行排序:

       SELECT * FROM `test`  order by project_id,create_time desc;

          

         然后对project_id分组:

      select * from (SELECT * FROM `test` order by project_id,create_time desc) t GROUP BY project_id;

         

         从分组后的结果可以看到:对于每一个分组,分组后的结果总是取组中主键(id)最小的数据,即group by project_id 总会对project_id执行排序(正序)

      而不论临时表(t)中的project_id是否已排序,然后取组中主键id最小(如id为1)的一行数据。换句话说 临时表t 内的排序 无法影响外层的group by 的操作。

       

        通过上面的实验可知  select * from (SELECT * FROM `test` order by project_id,create_time desc) t GROUP BY project_id; 无法获取项目的最新评论

        可以通过以下方法获取项目的最新评论:

        (1)

    SELECT
        t.* 
    FROM
        test t
        JOIN ( 
                SELECT 
                  SUBSTRING_INDEX( group_concat( id ORDER BY create_time DESC ), ',', 1 ) AS id 
                FROM 
                  test 
                GROUP BY project_id ) tmp 
        ON t.id = tmp.id;

           其结果为:

           

          分析结果可知,此为正确结果。

         注:group_concat 用法 (默认连接符为',')

              select  group_concat(project_id,'-',create_time,'-',status order by create_time desc SEPARATOR ',') as info from test GROUP BY project_id;

          

         SUBSTRING_INDEX 用法:下面的例子取排序好的分组的第一条数据

          

  • 相关阅读:
    团队作业 总结
    个人作业 Alpha项目测试
    第二次作业
    交互式多媒体图书平台的设计与实现
    基于VS Code的C++语言的构建调试环境搭建指南
    码农的自我修养之必备技能 学习笔记
    工程化编程实战callback接口学习
    如何测评一个软件工程师的计算机网络知识水平和编程能力
    深入理解TCP协议及其源代码
    Socket与系统调用深度分析
  • 原文地址:https://www.cnblogs.com/indifferent/p/14607692.html
Copyright © 2011-2022 走看看