文章目錄
一、分組函數(聚合函數)
1、介紹
分組查詢對數據行的集合進行操作並按組給出一個結果
2、格式
select [列名列表,] 分組函數(列)
from 表名
[where 條件語句]
[group by 列]
[having 關於 分組函數(列) 的條件表達式]
[order by 列 | 表達式]
3、常用函數
(1).MIN函數、MAX函數
使用示例
select min(hiredate), max(hiredate)
from emp;
注意點
min
或max
在沒有使用group by
子句的情況下,不要查詢其他列(因爲這樣沒有意義)
(2).SUM函數、AVG函數
使用示例
select max(sal) 最高工資, min(sal) 最低工資, avg(sal) 平均工資, sum(sal) 工資總和
from emp
where job="SALESMAN";
-- 發獎金的員工的平均獎金
select avg(comm) from emp;
-- 所有員工的平均獎金
select avg(ifnull(comm, 0)) from emp;
注意點
- 所有聚合函數在有
where
子句的情況下,where
子句會被執行,然後再分組 sum
函數、avg
函數不會對null
值進行統計,可以使用ifnull
函數強制對空值進行統計
(3).COUNT函數
使用示例
-- 員工人數
select count(*) from emp;
-- 拿薪水的員工人數
select count(sal) from emp;
-- 拿獎金的員工人數
select count(COMM) from emp;
-- 員工的部門數
select count(distinct deptno) from emp;
注意點
count
不會爲null
的列進行計數- 要消除重複行的計數需要加上關鍵字
distinct
4、group by子句
使用示例
-- 查詢所有部門的平均工資,並進行升序排列
select d.dname 部門名稱, avg(sal) 部門平均工資
from emp e
join dept d
on e.deptno = d.deptno
group by d.dname
order by 2;
-- 按每個部門、每個崗位顯示部門名稱、崗位、平均工資,並按照平均工資進行升序排列
select d.dname 部門名稱, e.job 崗位, avg(e.sal) 平均工資
from emp e
join dept d
on e.deptno = d.deptno
group by d.dname, e.job
order by avg(e.sal);
注意點
group by
中出現的列,儘可能出現在select中group by
中未出現的列,在select
中應該使用聚合函數
5、having子句
作用
使用having
子句排出組結果
使用示例
-- 查詢平均工資大於2900的部門
select d.dname, max(sal)
from emp e
join dept d
on e.deptno = d.deptno
group by d.dname
having max(sal) > 2900
--
select job, avg(sal) 平均工資
from emp
where job in ('CLERK', 'SALEMAN', 'MANAGER')
group by job
order by avg(sal);
注意點
where
子句不能限制分組函數的條件,必須用having
子句來限制- SQL語句執行順序:
select
(獲取表數據)→where
(篩選)→group by
(分組)→having
(篩選)→select
(整理分組後的數據)→order by
(排序)
二、子查詢(嵌套查詢)
1、單行子查詢
使用示例
-- 查詢比JONES員工工資高的其他員工
select ename
from emp
where sal > (select sal from emp where ename = 'JONES');
-- 錯誤示例
select ename
from emp
where sal > (select sal from emp where ename in ('JONES', 'SCOTT'));
注意點
- 不能拿單個值和嵌套查詢結果的多行值進行大小比較
2、多行子查詢
說明
子查詢返回的記錄條數也可以是多條,這時候往往就需要使用多行操作符(in
、any
、all
)
使用示例
-- 多列相等也可以直接等值判斷
select empno, ename, sal
from emo
where (ename, sal) = (select ename, sal from emp where empno = 7902);
-- 查詢管理者
select ename, sal
from emp
where empno in (select mgr from emp)
-- 查詢工資比JONES或SCOTT中的某一個大的所有員工
select ename, sal
from emp
where sal > any (select sal from emp where ename in ('JONES', 'SCOTT'));
-- 查詢工資比JONES或SCOTT中的所有都大的所有員工
select ename, sal
from emp
where sal > all (select sal from emp where ename in ('JONES', 'SCOTT'));
-- 查詢管理者的姓名和薪水
select ename, sal
from emp e
where empno exists (select mgr from emp m where m.mgr = e.empno)
-- 查詢不是管理者的員工的姓名和薪水
select ename, sal
from emp e
where empno not exists (select mgr from emp m where m.mgr = e.empno)
注意點
- 對於
any
和all
,可以近似理解爲數學意義上的存在
和任意
- 注意
null
值的處理,要使用exists
關鍵字而不是in
關鍵字