• MySQL数据分组GROUP BY 和HAVING


    对于分组的理解,可以这样:对GROUP BY子句后面跟随的列名进行分组,然后对每一个分组而不是整个表进行操作。

    举例如下:在产品表中,检索每一个供应商提供的商品的数量。

    mysql> SELECT vend_id,COUNT(*) AS num_prods FROM products GROUP BY vend_id;

    结果:

    +---------+-----------+
    | vend_id | num_prods |
    +---------+-----------+
    |    1001 |         3 |
    |    1002 |         2 |
    |    1003 |         7 |
    |    1005 |         2 |
    +---------+-----------+
    4 rows in set (0.01 sec)

    分析:

    首先根据vend_id进行分组,然后对每一个分组在进行COUNT聚集。当检索的目的是针对某种数据进行分组,统计的时候,想到用GROUP BY,例如这里是针对每一个供应商。

    GROUP BY的规定:

    1、GROUP BY 后面可以包含多个列,这就是嵌套。

    2、如果GROUP BY进行了嵌套,数据将在最后一个分组上进行汇总。

    3、GROUP BY子句中列出来的每个列必须是检索列或有效的表达式(但不能是聚集函数),如果在SELECT中使用了表达式,则必须在GROUP BY子句中指定相同的表达式。不能使用别名。

    4、除了聚集语句外,SELECT语句中的每一个列都必须在GROUP BY子句中给出。

    5、如果分组列中具有NULL值,则NULL将作为一个分组返回。如果列中有多个NULL,它们将作为一个分组返回。

    6、GROUP BY子句必须在WHERE 子句之后,ORDER BY 子句之前。

     过滤分组结果

    我们知道WHERE 子句用于过滤结果,但是对于分组的过滤WHERE子句不行。

    因为WHERE子句,是针对行的过滤。要对分组结果进行过滤,必须使用HAVING子句,HAVING子句能针对分组的结果进行过滤。

    举例:

    在订单表中,检索出具有两个以上订单的客户id以及订单数量。

    分析:

    在这个检索需求中,需要先根据客户id进行分组,然后过滤出订单数量大于2的分组。

    SELECT cust_id,COUNT(*) AS orders FROM orders GROUP BY cust_id HAVING orders>=2;

    结果:

    +---------+--------+
    | cust_id | orders |
    +---------+--------+
    |   10001 |      2 |
    +---------+--------+
    1 row in set (0.00 sec)

    与WHERE组合使用(先用WHERE过滤)

    有的时候,GROUP BY和WHERE子句也要组合使用。比如:在产品表中检索出能提供2个以上商品,并且价格高于10的供应商。

    分析:

    首先,检索的是供应商,因此SELECT子句应该是SELECT vend_id

    其次,产品表中,有价格这一列,因此对于价格高于10的条件的过滤要使用WHERE子句。SELECT vend_id FROM prodcuts WHERE prod_price>=10.

    接着,对vend_id进行分组,这样就可以得到每个vend_id的价格高于10的商品数量,GROUP BY放到WHERE子句后。SELECT vend_id FROM prodcuts WHERE prod_price>=10 GROUP BY vend_id.

    最后,对分组的结果过滤,过滤出2个以上商品的分组

    mysql> SELECT vend_id,COUNT(*) AS num_prods FROM products WHERE prod_price>=10 GROUP BY vend_id HAVING COUNT(*)>=2;

    结果:

    +---------+-----------+
    | vend_id | num_prods |
    +---------+-----------+
    |    1003 |         4 |
    |    1005 |         2 |
    +---------+-----------+
    2 rows in set (0.00 sec)

    对分组结果进行排序

    在订单明细表中,检索出订单总价格高于等于50的订单号以及订单总价格

    mysql> SELECT order_num,SUM(quantity*item_price) AS ordertotal FROM orderitems GROUP BY order_num HAVING SUM(quantity*item_price)>=50 ORDER BY ordertotal;
    结果是:

    +-----------+------------+
    | order_num | ordertotal |
    +-----------+------------+
    |     20006 |      55.00 |
    |     20008 |     125.00 |
    |     20005 |     149.87 |
    |     20007 |    1000.00 |
    +-----------+------------+
    4 rows in set (0.08 sec)

    SELECT 子句的顺序

    SELECT

    FROM 

    WHERE

    GROUP BY

    HAVING

    ORDER BY

    LIMIT

    
    
    
  • 相关阅读:
    POJ 3320 Jessica's Reading Problem
    引用参数和传值参数的区别
    IBM 的数据库Informix 常用代语法
    设计模式之原型模式
    UBoot中使用tftp下载文件出现错误TFTP error: 'Access violation' (2)的解决办法
    printf格式控制符的完整格式
    如何打印hostent结构体中的所有数据
    Informix 数据库客户端 dbvisualizer SQL Commander 乱码解决方案
    设计模式之模版方法模试
    nfs: server 192.168.37.200 not responding, still trying的解决办法
  • 原文地址:https://www.cnblogs.com/duhuo/p/5110590.html
Copyright © 2020-2023  润新知