having子句对已分组和汇总的结果表进行删除某些组操作。
having子句总是与group by子句一起使用,但是group by子句一般也可以单独使用。
having子句写在group by子句之后,order by子句之前。
一、应用示例:
1. 在员工表里查找员工数大于1的工作类型
--对员工表进行分组和汇总
SQL> select job_id,count(employee_id) num from employees group by job_id;
JOB_ID NUM
---------- ----------
AC_ACCOUNT 1
AC_MGR 1
AD_ASST 1
AD_PRES 1
AD_VP 2
FI_ACCOUNT 5
FI_MGR 1
HR_REP 1
IT_PROG 5
MK_MAN 1
MK_REP 1
PR_REP 1
PU_CLERK 5
PU_MAN 1
SA_MAN 5
SA_REP 30
SH_CLERK 20
ST_CLERK 20
ST_MAN 5
19 rows selected.
--having子句过滤
SQL> select job_id,count(employee_id) num from employees group by job_id having count(employee_id)>1;
JOB_ID NUM
---------- ----------
AD_VP 2
FI_ACCOUNT 5
IT_PROG 5
PU_CLERK 5
SA_MAN 5
SA_REP 30
SH_CLERK 20
ST_CLERK 20
ST_MAN 5
9 rows selected.
2. 用where 子句代替having子句
---having子句
SQL> select EMPLOYEE_ID,count(*) from employees group by EMPLOYEE_ID having EMPLOYEE_ID between 201 and 203;
EMPLOYEE_ID COUNT(*)
----------- ----------
201 1
202 1
203 1
---where子句
SQL> select EMPLOYEE_ID,count(*) from employees where EMPLOYEE_ID between 201 and 203 group by EMPLOYEE_ID;
EMPLOYEE_ID COUNT(*)
----------- ----------
201 1
202 1
203 1
二、having子句和where子句的不同之处:
1. where子句只能在进行任何处理之前从初始表的原始数据中删除行。
2. having子可以在进行绝大部分处理后删除已分组和已汇总的数据。
3. where子句不能在条件之中使用列函数。
4. having子句可在条件中使用列行数。
三、select语句执行顺序:
在一个表中使用select语句时的整个过程:
第1步:使用from子句选择初始表。
第2步:计算行函数。事实上,这是向初始表添加新列。
第3步:使用where子句选择表中哪些行的数据需要处理,删除不满足条件的行。
第4步:使用select子句选择要处理的数据列及在结果表中列出的数据列。包括在group by、having和order by子句中使用的其他列。删除其余的列。
第5步:group by子句将行分组。
第6步:列函数汇总每组的数据。
第7步:having子句选择将已汇总的数据行放到结果表中。
第8步:order by子句选择使用哪些列来对结果表所显示的行排序。
整理自《SQL编程基础》John J.Patrick