美文网首页读书笔记
《SQL基础教程》阅读笔记4

《SQL基础教程》阅读笔记4

作者: Athenaearl | 来源:发表于2018-11-18 14:25 被阅读9次

    子句书写顺序:
    SELECT->FROM ->WHERE-> GROUP BY ->HAVING ->ORDER BY

    聚合与排序

    对表进行聚合查询

    聚合函数

    用于汇总的函数称为聚合函数,所谓聚合就是将多行汇总为一行
    5个常用的聚合函数

    • COUNT 计算表中的记录数
    • SUM 计算表中数值列中数据的合计值
    • AVG 计算表中数值列中数据的平均值
    • MAX 计算表中数值列中数据的最大值
    • MIN 计算表中数值列中数据的最小值

    示例(COUNT):

    mysql> SELECT COUNT(*) FROM Product;
    +----------+
    | COUNT(*) |
    +----------+
    |        8 |
    +----------+
    1 row in set (0.00 sec)
    
    mysql> SELECT COUNT(purchase_price) FROM Product;
    +-----------------------+
    | COUNT(purchase_price) |
    +-----------------------+
    |                     6 |
    +-----------------------+
    1 row in set (0.00 sec)
    
    mysql> SELECT COUNT(*), COUNT(purchase_price) FROM Product;
    +----------+-----------------------+
    | COUNT(*) | COUNT(purchase_price) |
    +----------+-----------------------+
    |        8 |                     6 |
    +----------+-----------------------+
    1 row in set (0.00 sec)
    

    说明:
    COUNT(*) 代表的是计算所有的行数,就算有一行所有的值都是NULL,还是会被计算在内
    COUNT(列名) 代表的是这一列中所有不是NULL的行数

    示例(SUM):
    说明:SUM 会忽略掉所有的NULL,而不会将NULL加上去(所有NULL参与的运算的结果都是NULL),这里可以认为将NULL看作0来计算

    mysql> SELECT SUM(purchase_price), SUM(sale_price) FROM Product;
    +---------------------+-----------------+
    | SUM(purchase_price) | SUM(sale_price) |
    +---------------------+-----------------+
    |               12210 |           16780 |
    +---------------------+-----------------+
    1 row in set (0.00 sec)
    

    示例(AVG)
    可以将NULL看作是0来计算,但是本质上不是这么做的
    AVG做的就是将SUM的值/值的个数

    mysql> SELECT AVG(purchase_price), AVG(sale_price) FROM Product;
    +---------------------+-----------------+
    | AVG(purchase_price) | AVG(sale_price) |
    +---------------------+-----------------+
    |           2035.0000 |       2097.5000 |
    +---------------------+-----------------+
    1 row in set (0.00 sec)
    

    示例(MAX 和 MIN)

    mysql> SELECT MAX(regist_date), MIN(regist_date) FROM Product;
    +------------------+------------------+
    | MAX(regist_date) | MIN(regist_date) |
    +------------------+------------------+
    | 2009-11-11       | 2008-04-28       |
    +------------------+------------------+
    1 row in set (0.01 sec)
    

    使用聚合函数删除重复值(关键字 DISTINCT)

    回顾一下:使用count函数
    如果count(单列列名) 返回的是该列非NULL的行数
    如果count(*) 返回的是所有的行数
    如果想要获得没有重复值的行数,则需要DISTINCT关键字

    mysql> SELECT COUNT(DISTINCT product_type) FROM Product;
    +------------------------------+
    | COUNT(DISTINCT product_type) |
    +------------------------------+
    |                            3 |
    +------------------------------+
    1 row in set (0.00 sec)
    

    对表进行分组

    mysql> SELECT product_type, COUNT(*) FROM Product GROUP BY product_type;
    +--------------+----------+
    | product_type | COUNT(*) |
    +--------------+----------+
    | 办公用品     |        2 |
    | 厨房用具     |        4 |
    | 衣服         |        2 |
    +--------------+----------+
    3 rows in set (0.00 sec)
    

    说明:
    这里的意思是,打印 product_type 和 count 的值,这些值来自于根据product_type 分的组中,也就是说这里面分了三组,分别是 办公用具、厨房用具、衣服 ,count则是分别计算每一组出现的次数
    而且,如果有NULL的话,NULL会被单独算一组

    加入where子句
    mysql> SELECT product_type, COUNT(*) FROM Product WHERE regist_date = '2009-09-20' GROUP BY product_type;
    +--------------+----------+
    | product_type | COUNT(*) |
    +--------------+----------+
    | 厨房用具     |        2 |
    | 衣服         |        1 |
    +--------------+----------+
    2 rows in set (0.00 sec)
    

    说明:先找到时间是2009-09-20的行,然后按照product_type 分的类,办公用品这一类没有这个时间注册的,因此没有这一项,计数时候,厨房用品这一天的有2件因此count的值为2

    常见错误:

    1. SELECT col1, col2 FROM product GROUP BY col1;
      这种形式是允许的,因为,比如col1 代表时间,col2 代表产品种类,可能一个时间有多个产品被登记,那么就会导致混乱,因此这种形式是不被允许的
    2. GROUP BY 语句中使用别名:
      SELECT col1 AS name1 FROM product GROUP BY name1;
      这是由于内部的执行顺序导致的,在进行到分组时候,它还不知道别名是什么。但是这个分数据库管理系统,比如笔者用的Mysql就不会导致错误。但是这不是标准的sql语句
    3. 认为GROUP BY输出的结果是排好序的:
      实际上其输出结果是随机的,如果想要排序,需要进行指定
    4. 在WHERE 子句中使用聚合函数:
    SELECT product_type, COUNT(*)
    FROM product
    WHERE COUNT(*) = 2
    GROUP BY product_type;
    

    这种写法是错误的。实际上想要达到效果,应该使用having 子句
    只有SELECT 、HAVING、ORDER BY子句可以使用聚合函数

    此外:
    可以注意到:

    SELECT DISTINCT product_type FROM product;
    

    SELECT product_type FROM product GROUP BY product_type;
    

    得到的效果是一样的

    为聚合结果指定条件

    WHERE 能够指定的是行条件,而HAVING 则是可以指定组条件,因此HAVING 子句可以使用聚合函数

    mysql> SELECT product_type, COUNT(*) FROM Product GROUP BY product_type HAVING COUNt(*)=2;
    +--------------+----------+
    | product_type | COUNT(*) |
    +--------------+----------+
    | 办公用品     |        2 |
    | 衣服         |        2 |
    +--------------+----------+
    2 rows in set (0.00 sec)
    

    说明:
    表中根据product_type 分类,但是只选择那些count值为2 的组

    WHERE是先将满足条件的行挑出来,然后再分组

    而HAVING 是先分组然后再将合适的组挑出来,因此HAVING只能是组的条件,行条件是不可以的。但是,由于分组是根据一个列来分组,那么HAVING 可以使用这个列的条件
    即:

    SELECT col1 FROM table GROUP BY col1 HAVING col1 = col1_element1;
    

    但是想要这种情况的话 WHERE 也可以做到,甚至来说,更加推荐用WHERE

    对查询结果进行排序

    ORDER BY 子句

    mysql> SELECT product_type, product_name FROM Product ORDER BY sale_price;
    +--------------+--------------+
    | product_type | product_name |
    +--------------+--------------+
    | 办公用品     | 圆珠笔       |
    | 办公用品     | 打孔机       |
    | 厨房用具     | 叉子         |
    | 厨房用具     | 擦菜板       |
    | 衣服         | T恤衫        |
    | 厨房用具     | 菜刀         |
    | 衣服         | 运动T恤      |
    | 厨房用具     | 高压锅       |
    +--------------+--------------+
    8 rows in set (0.00 sec)
    
    mysql> SELECT product_type, product_name FROM Product ORDER BY sale_price DESC;
    +--------------+--------------+
    | product_type | product_name |
    +--------------+--------------+
    | 厨房用具     | 高压锅       |
    | 衣服         | 运动T恤      |
    | 厨房用具     | 菜刀         |
    | 衣服         | T恤衫        |
    | 厨房用具     | 擦菜板       |
    | 办公用品     | 打孔机       |
    | 厨房用具     | 叉子         |
    | 办公用品     | 圆珠笔       |
    +--------------+--------------+
    8 rows in set (0.00 sec)
    
    mysql> SELECT product_type, product_name FROM Product ORDER BY sale_price DESC, product_id;
    +--------------+--------------+
    | product_type | product_name |
    +--------------+--------------+
    | 厨房用具     | 高压锅       |
    | 衣服         | 运动T恤      |
    | 厨房用具     | 菜刀         |
    | 衣服         | T恤衫        |
    | 厨房用具     | 擦菜板       |
    | 办公用品     | 打孔机       |
    | 厨房用具     | 叉子         |
    | 办公用品     | 圆珠笔       |
    +--------------+--------------+
    8 rows in set (0.00 sec)
    

    说明:

    1. 排序键可以使用别名
    2. 可以使用聚合函数
    3. 可以用数字来代指SELECT 子句中第几个元素
      SELECT col1, col2 ,col3 FROM table ORDER BY 2 DESC , 1;
      代表 按 col2 的降序排,按col1 的升序排。但是不推荐使用,不易于使用

    相关文章

      网友评论

        本文标题:《SQL基础教程》阅读笔记4

        本文链接:https://www.haomeiwen.com/subject/ayedfqtx.html