《SQL高級應用和數據倉庫基礎(MySQL版)》學習筆記 ·010【高級查詢】

一、分組函數(聚合函數)

1、介紹

分組查詢對數據行的集合進行操作並按組給出一個結果

2、格式

select [列名列表,] 分組函數()
from 表名
[where 條件語句]
[group by]
[having 關於 分組函數() 的條件表達式]
[order by| 表達式]

3、常用函數

(1).MIN函數、MAX函數

使用示例

select min(hiredate), max(hiredate)
from emp;

注意點

  • minmax在沒有使用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、多行子查詢

說明
子查詢返回的記錄條數也可以是多條,這時候往往就需要使用多行操作符(inanyall

使用示例

-- 多列相等也可以直接等值判斷
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)

注意點

  • 對於anyall,可以近似理解爲數學意義上的存在任意
  • 注意null值的處理,要使用exists關鍵字而不是in關鍵字
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章