1. 程式人生 > >SQL 資料庫 學習 028 查詢-11 having --- 對分組之後的資訊進行過濾

SQL 資料庫 學習 028 查詢-11 having --- 對分組之後的資訊進行過濾

  • 我的電腦系統:Windows 10 64位
  • SQL Server 軟體版本: SQL Server 2014 Express

本篇部落格裡面使用了 scott 庫,如何你現在還沒有新增這個庫到你的伺服器裡面,請在檢視本篇部落格前,訪問這篇博文來在你的伺服器裡面附加scott庫。

having — 對分組之後的資訊進行過濾

--輸出部門平均工資大於2000的部門的部門編號,部門的平均工資
select deptno, avg(sal)
    from emp
    group by deptno
    having avg(sal)>2000;

Alt text

加入別名。

--判斷下列sql語句是否正確
select deptno, avg(sal) as "平均工資" from emp group by deptno having avg(sal) > 2000

Alt text

--error
select deptno, avg(sal) as "平均工資"
    from emp
    group by deptno
    having "平均工資" > 2000

Alt text

正確的指令:

select deptno, avg(sal)
    from emp
    where ename not like '%A%'
    group by deptno
    having
avg(sal) > 2000
--以部門編號分組後,顯示組內元組大於3個元組的部門編號和平均工資
select deptno, avg(sal) as "平均工資"
    from emp
    group by deptno
    having count(*) > 3

Alt text

--error
select deptno, avg(sal) as "平均工資"
    from emp
    group by deptno
    having ename like '%A%'

Alt text

select deptno, avg(sal) as "平均工資"
    from
emp group by deptno having deptno>1

Alt text

havingwhere 的異同

--把姓名不包含`A`的所有的員工按部門編號分組,
--統計輸出部門平均工資大於2000的部門的部門編號、部門的平均工資
select deptno, avg(sal)
    from emp
    where ename not like '%A%'
    group by deptno
    having avg(sal) > 2000

Alt text

--把工資大於2000,
--統計輸出部門平均工資大於3000的部門的部門編號、部門的平均工資、部門人數、部門最高工資
select deptno, avg(sal) "平均工資", count(*) "部門人數", max(sal) "部門最高工資"
    from emp
    where sal > 2000    --where是對原始的記錄過濾
    group by deptno   
    having avg(sal) > 3000   --對分組之後的記錄過濾 

Alt text

如果引數的順序變化了,執行的時候會不會受到影響?執行下面的指令,你就會知道答案。

--error
select deptno, avg(sal) "平均工資", count(*) "部門人數", max(sal) "部門最高工資"
    from emp
    group by deptno
    having avg(sal) > 3000
    where sal > 2000

Alt text

總結: 所有select 的引數的順序是不允許變化的(所有的引數的位置都是固定的,你可以省略某個引數,但是不能變。),否則編譯時出錯。

havingwhere 的異同:

  • 相同: 都是對資料過濾,只保留有效的資料。wherehaving 一樣,都不允許出現欄位的別名,只允許出現最原始的欄位的名字。
--error where子句不應該出現聚合函式
select deptno, avg(sal)
    from emp
    where avg(sal) > 2000   --error 因為where是對原始的資料過濾,不能使用聚合函式
  • 不同: where 是對原始的記錄過濾,having 是對分組之後的記錄過濾。where 必須得寫在having的前面,順序不可顛倒,否則執行出錯。

總結 having 的用法

  1. having 子句是用來對分組之後的資料進行過濾。因此使用having時通常都會先使用 group by
  2. 如果沒有使用 group by ,而使用了 having,則意味著 having 把所有的記錄當做一組來進行過濾。
select count(*) 
    from emp
    having avg(sal) > 1000
  1. having 子句出現的欄位必須得是分組之後的組的整體資訊。having 子句不允許出現組內的詳細資訊。
--error
select deptno avg(sal) as "平均工資", job
    from emp
    group by deptno
--OK
select deptno avg(sal) as "平均工資", count(*) as "部門人數"
    from emp
    group by deptno
  1. 儘管 select 欄位中可以出現別名。但是having 子句中不能出現欄位的別名,只能使用欄位最原始的名字。(原因不得而知。)

  2. 就是上面說的:havingwhere 的異同 。(這裡不重複說明了。)