mysql必知必会-笔记 12-15章

12章 汇总数据

聚集函数(aggregate function) 运行在行组上,计算和返回单个值的函数

1. 确定表中行数(或者满足某个条件或包含某个特定值的行数)。
2. 获得表中行组的和。
3. 找出表列(或所有行或某些特定的行)的最大值、最小值和平均值。

SQL聚集函数
函 数                 说 明
AVG()           返回某列的平均值
COUNT()         返回某列的行数
MAX()           返回某列的最大值
MIN()           返回某列的最小值
SUM()           返回某列值之和

举例:
AVG()函数
mysql> select avg(prod_price) as avg_price from products;
mysql> select avg(prod_price) as avg_price from products where vend_id = 1003;  //指定条件
+-----------+
| avg_price |
+-----------+
| 13.212857 |
+-----------+

COUNT()函数
检索客户总数:
mysql> select count(*) as num_cust from customers;
+----------+
| num_cust |
+----------+
|        5 |
+----------+
COUNT()函数有两种使用方式:
1. 使用COUNT(*)对表中行的数目进行计数,不管表列中包含的是空值(NULL)还是非空值。
2. 使用COUNT(column)对特定列中具有值的行进行计数,忽略NULL值。
mysql> select count(cust_email) as num_cust from customers; //只对具有电子邮件地址的客户计数

MAX()函数
返回指定列中的最大值, 需要指定列名, MAX()函数忽略列值为NULL的行。
mysql> select max(prod_price) as max_pricce from products;

MIN()函数
返回指定列的最小值。与MAX()一样,MIN()要求指定列名,忽略列值为NULL的行

SUM()函数
mysql> select quantity from orderitems where order_num= 20005;
+----------+
| quantity |
+----------+
|       10 |
|        3 |
|        5 |
|        1 |
+----------+
mysql> select sum(quantity) as items_ordered from orderitems where order_num= 20005;
+---------------+
| items_ordered |
+---------------+
|            19 |
+---------------+

聚集不同值

使用DISTINCT
mysql> select avg(distinct prod_price) as avg_price from products where vend_id = 1003;
+-----------+
| avg_price |
+-----------+
| 15.998000 |
+-----------+
使用了DISTINCT后,此例子中的avg_price比较高,因为有多个物品具有相同的较低价格。排除它们提升了平均价格。

组合聚集函数
mysql> select count(*) as num_items, min(prod_price) as price_min,max(prod_price) as price_max, avg(prod_price) as prive_avg from products;
+-----------+-----------+-----------+-----------+
| num_items | price_min | price_max | prive_avg |
+-----------+-----------+-----------+-----------+
| 14 | 2.50 | 55.00 | 16.133571 |
+-----------+-----------+-----------+-----------+

13章 分组数据

group by 分组允许把数据分为多个逻辑组,以便能对每个组进行聚集计算.

创建分组

mysql> select vend_id, count(*) as num_prods from products;
+---------+-----------+
| vend_id | num_prods |
+---------+-----------+
|    1001 |        14 |
+---------+-----------+ 
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 |
+---------+-----------+
在具体使用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子句之前。

过滤分组

HAVING子句

1. HAVING非常类似于WHERE, 所有类型的WHERE子句都可以用HAVING来替代。唯一的差别是WHERE过滤行,而HAVING过滤分组。
2. HAVING支持所有WHERE操作符
mysql> select cust_id, count(*) as orders from orders group by cust_id having count(*)>=2;
+---------+--------+
| cust_id | orders |
+---------+--------+
|   10001 |      2 |
+---------+--------+
这里WHERE子句不起作用,因为过滤是基于分组聚集值而不是特定行值的
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 |
+---------+-----------+

分组和排序

ORDER BY与GROUP BY
        ORDER BY                        GROUP BY
+--------------------------+--------------------------------------------------
|   排序产生的输出           |    分组行。但输出可能不是分组的顺序                 
+--------------------------+--------------------------------------------------
|   任意列都可以使用(甚至    |    只可能使用选择列或表达式列,而且必须使用每个选择    
|   非选择的列也可以使用)    |    列表达式                                      
+--------------------------+--------------------------------------------------
|   不一定需要              |    如果与聚集函数一起使用列(或表达式),则必须使用        
+--------------------------+--------------------------------------------------

mysql> select order_num,sum(quantity*item_price) as ordertotal from orderitems group by order_num having sum(quantity*item_price)>=50;
+-----------+------------+
| order_num | ordertotal |
+-----------+------------+
|     20005 |     149.87 |
|     20006 |      55.00 |
|     20007 |    1000.00 |
|     20008 |     125.00 |
+-----------+------------+
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 |
+-----------+------------+

SELECT子句顺序

SELECT子句及其顺序: 以下为必须遵循的顺序。
子 句         说 明                         是否必须使用
SELECT      要返回的列或表达式           是
FROM        从中检索数据的表                仅在从表选择数据时使用
WHERE       行级过滤                    否
GROUP BY    分组说明                    仅在按组计算聚集时使用
HAVING      组级过滤                    否
ORDER BY    输出排序顺序                  否
LIMIT       要检索的行数                  否

14章 使用子查询

子查询(subquery),即嵌套在其他查询中的查询。

mysql> select cust_id from orders where order_num in (select order_num from orderitems where prod_id='TNT2');
+---------+
| cust_id |
+---------+
|   10001 |
|   10004 |
+---------+
嵌套查询顺序:子查询总是从内向外处理

15章 联结表

一些概念:

1.  联结是一种机制,用来在一条SELECT语句中关联表,因此称之为联结
2.  外键(foreign key): 外键为某个表中的一列,它包含另一个表的主键值,定义了两个表之间的关系。
3.  如果数据存储在多个表中,怎样用单条SELECT语句检索出数据?答案是使用联结
4.  SQL最强大的功能之一就是能在数据检索查询的执行中联结(join)表。

举例:

mysql> select vend_name, prod_name,prod_price from vendors,products 
   --> where vendors.vend_id = products.vend_id order by vend_name,prod_name;
+-------------+----------------+------------+
| vend_name   | prod_name      | prod_price |
+-------------+----------------+------------+
| ACME        | Bird seed      |      10.00 |
| ACME        | Carrots        |       2.50 |
| ACME        | Detonator      |      13.00 |
| ACME        | Safe           |      50.00 |
| ACME        | Sling          |       4.49 |
| ACME        | TNT (1 stick)  |       2.50 |
| ACME        | TNT (5 sticks) |      10.00 |
| Anvils R us | .5 ton anvil   |       5.99 |
| Anvils R us | 1 ton anvil    |       9.99 |
| Anvils R us | 2 ton anvil    |      14.99 |
| Jet Set     | JetPack 1000   |      35.00 |
| Jet Set     | JetPack 2000   |      55.00 |
| LT Supplies | Fuses          |       3.42 |
| LT Supplies | Oil can        |       8.99 |
+-------------+----------------+------------+
这里,最大的差别是所指定的两个列(prod_name  和prod_price)在一个表中,而另一个列(vend_name)在另一个表中。
通过where子句连接: where vendors.vend_id = products.vend_id

笛卡儿积(cartesian product) 由没有联结条件的表关系返回的结果为笛卡儿积, 笛卡尔积不是我们想要的结果

mysql> select vend_name, prod_name,prod_price from vendors,products order by vend_name,prod_name; //没有where过滤

内部联结 inner join

下面语句返回与上面相同的结果:
mysql> select vend_name,prod_name, prod_price from vendors inner join products on vendors.vend_id = 
   --> products.vend_id order by vend_name, prod_name;
+-------------+----------------+------------+
| vend_name   | prod_name      | prod_price |
+-------------+----------------+------------+
| ACME        | Bird seed      |      10.00 |
| ACME        | Carrots        |       2.50 |
| ACME        | Detonator      |      13.00 |
| ACME        | Safe           |      50.00 |
| ACME        | Sling          |       4.49 |
| ACME        | TNT (1 stick)  |       2.50 |
| ACME        | TNT (5 sticks) |      10.00 |
| Anvils R us | .5 ton anvil   |       5.99 |
| Anvils R us | 1 ton anvil    |       9.99 |
| Anvils R us | 2 ton anvil    |      14.99 |
| Jet Set     | JetPack 1000   |      35.00 |
| Jet Set     | JetPack 2000   |      55.00 |
| LT Supplies | Fuses          |       3.42 |
| LT Supplies | Oil can        |       8.99 |
+-------------+----------------+------------+

联结多个表

mysql> select vend_name,prod_name, prod_price from vendors ,orderitems, products where products.vend_id =
    --> vendors.vend_id and orderitems.prod_id = products.prod_id and order_num = 20005;
+-------------+----------------+------------+
| vend_name   | prod_name      | prod_price |
+-------------+----------------+------------+
| Anvils R us | .5 ton anvil   |       5.99 |
| Anvils R us | 1 ton anvil    |       9.99 |
| ACME        | TNT (5 sticks) |      10.00 |
| ACME        | Bird seed      |      10.00 |
+-------------+----------------+------------+

你可能感兴趣的:(mysql必知必会-笔记 12-15章)