group by 按组分隔

  1. SELECT purchase_price , COUNT(*)
  2. from product
  3. GROUP BY product_type ;
  4. +----------------+----------+
  5. | purchase_price | count(*) |
  6. +----------------+----------+
  7. | 80 | 2 |
  8. | 160 | 1 |
  9. | NULL | 2 |
  10. +----------------+----------+

关于group by在语句中执行顺序

from -> where -> group by -> select

group by语句书写时容易引发的错误和注意事项

  1. from 前面的的查询字段中,和group by 对应不上,会引起逻辑错误
  2. group by 使用as 别名,因为按照执行来说,是先执行group by语句,所以select子句中的as和后面group by中的子句无法做到映射,在group by中不要使用别名(观看上面的group by在语句中的执行顺序可得知 )
  3. group by 结果中无法进行排序
  4. where中使用聚合函数(只有在select和having,order by这样的子句才能够使用聚合函数)

group by 和 distinct

虽然很多时候使用他们返回的结果一样,但是从语义化上面来说的话,group by是对查询结果进行汇总,而distinct是删除查询结果的重复项。

having 有

/* 
  select product_type , COUNT(*)
  from product
  GROUP BY product_type的结果做过滤,只挑选条数大于1的结果
*/

select product_type , COUNT(*)
from product
GROUP BY product_type
HAVING COUNT(*) > 1;

having执行顺序

-- having务必要写在group by之后 --
select -> from -> where -> group by -> having

having子句需要构成要素

  1. 常数
  2. 聚合函数
  3. 聚合建 ```sql — count() 为聚合函数 1为常数 — HAVING COUNT() > 1;

— product_type 为聚合键 衣服为常数 — HAVING product_type = ‘衣服’;

— 上面这两种其实都是可以的,但是注意的是如果出现的是下面出现的字段务必要是聚合键,否则会有报错 —

<a name="UHnAq"></a>
### having和where的区别
having和where的条件都是聚合键所对应的条件,虽然他们和group by组合所达成的效果是一样的,但是具体达成的方式是不一样的

- having 是针对组进行操作
- where 是针对行进行操作

所以,相对于聚合键的条件,它更适合与where进行搭配
<a name="JFDBt"></a>
#### 关于having和where执行速度
先说结论,having和where相比,where的执行速度会快很多!<br />这样从DBMS运行机制和having的执行顺序来说,在进行count(*)的时候,DBMS会对数据进行排序,这是非常的损耗性能的,但是拥有where子句的sql语句,是进行了过滤之后在进行排序,而having是经过过滤之后在进行过滤的,所以通过这一过滤数据量一对比,明显可以看到where的优势。<br />不仅如此,where子句可以指定条件所对应的列添加索引,这样也会对排序速度进行提升。


<a name="e2dXm"></a>
## order by 排序
简单的升降
```sql
-- 通过purchase_price进行升序排列 默认 asc --
select product_id , product_name , purchase_price 
from product 
ORDER BY purchase_price;

+------------+--------------+----------------+
| product_id | product_name | purchase_price |
+------------+--------------+----------------+
| 0004       | ??           |           NULL |
| 0005       | ??           |           NULL |
| 0001       | ??           |             80 |
| 0003       | ??           |             80 |
| 0002       | ???          |            160 |
+------------+--------------+----------------+

-- 通过purchase_price进行升序排列 desc --
select product_id , product_name , purchase_price 
from product 
ORDER BY purchase_price desc;

+------------+--------------+----------------+
| product_id | product_name | purchase_price |
+------------+--------------+----------------+
| 0002       | ???          |            160 |
| 0001       | ??           |             80 |
| 0003       | ??           |             80 |
| 0004       | ??           |           NULL |
| 0005       | ??           |           NULL |
+------------+--------------+----------------+

多个排列键进行排列

-- 我们可以在order by 后面的子句中添加多个排列键进行多项排列 --

null顺序
可以看到null呗当成0看待了

可以使用任意排列键
select子句中未出现的键名可以在order by子句中出现

可以使用别名 ( 执行顺序 )
由于执行顺序的关系的,select子句中的as我们在order by中是可以使用的

from ->  where -> by group ->  select ->  order by -> having

子句可以使用聚合函数
不看了,累了,累了

可以使用列名,但是不推荐使用
不写了