MYSQL中GROUP BY不包含所有的非聚合字段时的注意事项

MYSQL中GROUP BY不包含所有的非聚合字段时的注意事项

一、下列语句在MySql中是合规的

  •  
  • 
    select count(1),task_type,status from action where biz_date='20141014' group by status
    
    
    select count(1),task_type from action where biz_date='20141014' group by status
    
    
    		
  • 二、使用时易出现的问题

    1、实例数据

  •  
  • 
    mysql> select * from test;
    
    
    +----+-------+------+-------+
    | id | name  | age  | class |
    +----+-------+------+-------+
    |  1 | qiu   |   22 |     1 | 
    |  2 | liu   |   42 |     1 | 
    |  4 | zheng |   20 |     2 | 
    |  3 | qian  |   20 |     2 | 
    |  0 | wang  |   11 |     3 | 
    |  6 | li    |   33 |     3 | 
    +----+-------+------+-------+
    6 rows in set (0.00 sec)
    
    		
  • 2、找到每个class里面的最大的age的基本信息

    如下的sql语句,则输出结果不准确

  • 
    mysql> select id,name,max(age),class from test group by class;
    
    +----+-------+----------+-------+
    | id | name  | max(age) | class |
    +----+-------+----------+-------+
    |  1 | qiu   |       42 |     1 | 
    |  4 | zheng |       20 |     2 | 
    |  0 | wang  |       33 |     3 | 
    +----+-------+----------+-------+
    3 rows in set (0.00 sec)
    
    		
  • 备注

    虽然找到的age是最大的age,但是与之匹配的用户信息却不是真实的信息

    原因

    如果 id,name 不能唯一确定的话,mysql会随机选一行做为值。

    三、使用是注意事项

    1、这个写法不标准, 因为假如没group的字段如果有多个值, 可能导致这个字段会有不确定的值,且不利于数据库移植

    2、假如可以确定这个字段都是重复的值(譬如多表联接), 那就没有这方面的困扰,反而会简化SQL语句,也有可能会提高性能,可以推荐这种方式查询

    例如

  •  
  • 
    select A.id, B.desc, B.XXX, B.YYY SUM(A.AMT) 
        FROM A
        join b on a.id=b.id
        where a.id=? and b.xxx=?
        group a.id
    
    		
  • 标签: