> 文章列表 > MySQL进阶用法(Case WHEN、HAVING、SQL语句执行顺序)

MySQL进阶用法(Case WHEN、HAVING、SQL语句执行顺序)

MySQL进阶用法(Case WHEN、HAVING、SQL语句执行顺序)

HAVING

在 SQL 中增加 HAVING 子句原因是,WHERE 关键字无法与聚合函数一起使用。
HAVING 子句可以让我们筛选分组后的各组数据。

SELECT column_name, aggregate_function(column_name)
FROM table_name
WHERE column_name operator value
GROUP BY column_name
HAVING aggregate_function(column_name) operator value;

例如:查找总访问量大于 200 的网站

SELECT Websites.name, Websites.url, SUM(access_log.count) AS nums FROM (access_log
INNER JOIN Websites
ON access_log.site_id=Websites.id)
GROUP BY Websites.name
HAVING SUM(access_log.count) > 200;

where 和having之后都是筛选条件,但是是有区别的:

  • where在group by前, having在group by 之后
  • 聚合函数(avg、sum、max、min、count),不能作为条件放在where之后,但可以放在having之后

CASE WHEN

MySQL 的 case when 的语法有两种:
简单函数CASE [col_name] WHEN [value1] THEN [result1]…ELSE [default] END

SELECTNAME '英雄',CASE NAMEWHEN '德莱文' THEN'斧子'WHEN '德玛西亚-盖伦' THEN'大宝剑'WHEN '暗夜猎手-VN' THEN'弩'ELSE'无'END '装备'
FROMuser_info;

搜索函数CASE WHEN [expr] THEN [result1]…ELSE [default] END

# when 表达式中可以使用 and 连接条件
SELECTNAME '英雄',age '年龄',CASEWHEN age < 18 THEN'少年'WHEN age < 30 THEN'青年'WHEN age >= 30AND age < 50 THEN'中年'ELSE'老年'END '状态'
FROMuser_info;

SQL语句执行顺序

要想优化慢SQL语句首先需要了解SQL语句的执行顺序,SQL语句中的各关键词执行顺序如下:

  • 首先执行from、join 来确定表之间的连接关系,得到初步的数据。
  • 然后利用where 对数据进行初步筛选。
  • group by 分组
  • 各组分别执行having 中的普通筛选或者聚合函数筛选。
  • 然后把再根据我们要的数据进行select,可以是普通字段查询也可以是获取聚合函数的查询结果,如果是集合函数,select的查询结果会新增一条字段
  • 将查询结果去重distinct
  • 最后合并各组的查询结果,按照order by的条件进行排序

SQL关键字的顺序

SELECT ... FROM ... WHERE ... GROUP BY ... HAVING ... ORDER BY ...

SELECT语句的执行顺序(在MySQL和Oracle中,SELECT执行顺序基本相同):

FROM ... JOIN > WHERE > GROUP BY > HAVING > SELECT的字段 > DISTINCT > ORDER BY > LIMIT

在SELECT语句执行这些步骤的时候,每个步骤都会产生一个虚拟表,然后将这个虚拟表传入下一个步骤中作为输入。需要注意的是,这些步骤隐含在SQL的执行过程中,对于我们来说是不可见的。