1. 程式人生 > 資料庫 >sql第四天

sql第四天

排序分組

排序

語法:

SELECT COLUMN1,COLUMN2,COLUMN3 FROM TABLE_NAME (WHERE COMDITION) ORDER BY COLUMN1 ASC/DESC;

應用:將員工資訊按照工資升序排列

SELECT * FROM EMP ORDER BY SAL ASC;

應用:

SELECT EMPNO,ENAME,SAL,SAL*12,JOB FROM EMP ORDER BY 1 ;--按照MPNO,ENAME,SAL,SAL*12,JOB這幾列中的第1列排序
SELECT EMPNO,ENAME,SAL,SAL*12,JOB FROM EMP ORDER BY 8 ;--報錯,因為前面查詢的列中沒有第8列
SELECT EMPNO,ENAME,SAL,SAL*12,JOB FROM EMP ORDER BY DEPTNO,SAL ;--可以跟多列排序,首先按照第一列排序,如果第一列的值相等,再按第二列排序
SELECT * FROM EMP ORDER BY DEPTNO DESC,SAL ASC;--規則上一個排序列對應一個排序方式
SELECT EMPNO,ENAME,SAL,JOB FROM EMP ORDER BY 'A';--沒有意義
SELECT * FROM EMPORDER BY COMM ASC;--有NULL值時預設視為最大
SELECT * FROM EMP ORDER BY COMM ASC NULLS LAST;
SELECT * FROM EMP ORDER BY COMM ASC NULLS FIRST;

將NULL值自定義前後排序順序

ROWNUM

ROWNUM:性質是偽列 /可以查詢的/查詢結果為一組遞增的數字

ROWNUM的應用:

SELECT EMPNO,ENAME,SAL,JOB,ROWNUM FROM EMP;


在這裡插入圖片描述
加粗樣式

在這裡插入圖片描述
應用:查詢EMP 表中ROWNUM為1,2,3的員工資訊

SELECT EMP.*,ROWNUM FROM EMP WHERE ROWNUM<=3;--每次有多個表名出現時,應當在萬用字元 *前註明表名

注意:
1.ROWNUM只能用於小於等於查詢(有破解方法,給rownum起別名)
2.條件語句中不能使用別名但是排序時可以使用
3.排序可以跟運算使用;比如先運算求日薪再排序

分組查詢

SELECT COLUMN1 FROM EMP (WHERE CONDITION) GROUP BY COLUMN1 HAVING CONDITION;

在這裡插入圖片描述
應用:查詢每個部門各自的工資總和

SELECT DEPTNO,SUM(SAL) FROM EMP GROUP BY DEPTNO;

查詢每個部門的員工人數

SELECT DEPTNO,COUNT(*) FROM EMP GROUP BY DEPTNO;

思考下列語句是查詢什麼的?

SELECT DEPTNO,JOB,COUNT(*) FROM EMP GROUP BY DEPTNO,JOB;


統計各自部門的各自職業的人數

在這裡插入圖片描述

應用:按照部門和職業分組並且排序統計各自部門的各自職業的人數

SELECT DEPTNO,JOB,COUNT(*) FROM EMP GROUP BY DEPTNO,JOB ORDER BY DEPTNO;

應用:查詢平均工資大於2000的每個部門的員工人數,和每個部門平均工資

SELECT DEPTNO,COUNT(*),AVG(SAL) FROM EMP GROUP BY DEPTNO  HAVING AVG(SAL)>2000;

–為什麼這個地方不用WHERE而是用HAVING?因為where後不允許使用聚合函式,而且注意where的位置和having的位置不一樣

注意:WHERE 和HAVING 的聯絡:
1.WHERE不必和 GROUP BY連用,不能寫在 GROUP BY後,HAVING和 GROUP BY連用
2.WHERE篩選的是針對FROM後表的資料, HAVING是針對 GROUP BY分組之後的資料進行篩選
3.WHERE中的部分條件可以寫在 HAVING中,只有在 GROUP BY子句中出現的欄位,才能夠由WHERE子句中轉寫到HAVING子句中

練習:
1.查詢每個部門的平均工資,並統計其員工人數

SELECT DEPTNO,AVG(SAL),COUNT(*) FROM EMP GROUP BY DEPTNO;

2.查詢每個部門的平均工資,最大工資,最小工資

SELECT DEPTNO,MAX(SAL),MIN(SAL),AVG(SAL) FROM EMP GROUP BY DEPTNO;

3.查詢每個平均工資大於2000部門編號/最大最小及平均工資

SELECT DEPTNO,MAX(SAL),MIN(SAL),AVG(SAL) FROM EMP GROUP BY DEPTNO HAVING AVG(SAL)>2000;

習題:
1.查詢emp表,將職位為 ANALYST, CLERK和 SALESMAN的顯示為工人, MANAGER和 PRESIDEN顯示為管理員

SELECT JOB,CASE WHEN JOB='ANALYST' THEN '工人'
WHEN JOB='CLERK' THEN '工人'
WHEN JOB='SALESMAN' THEN '工人'
WHEN JOB='MANAGER' THEN '管理員'
WHEN JOB='PRESIDENT' THEN '管理員'
END FROM EMP;
  • 2.列出所有員工的年工資,按年薪從低到高排序(年薪=sal*12+ comm);
SELECT EMP.*,SAL*12+NVL(COMM,0) AS "年薪" FROM EMP ORDER BY 年薪;

3.查詢emp表,若SAL大於2500,則顯示為高收入,1000-2500顯示為中等收入,低於1000顯示為貧農

SELECT SAL,CASE WHEN SAL>2500 THEN '高收入' WHEN SAL BETWEEN 1000 AND 2500 THEN '中等收入' WHEN SAL<1000 THEN '貧農' END FROM EMP;

4.查詢emp表,查詢出SAL<1000,SAL在1000-3000,和SAL大於3000的人數

SELECT SUM(CASE WHEN SAL<1000 THEN 1 ELSE 0 END),SUM(CASE WHEN SAL BETWEEN 1000 AND 3000 THEN 1 ELSE 0 END),SUM(CASE WHEN SAL>3000 THEN 1 ELSE 0 END) FROM EMP;

5.查詢emp表,要求按照 hiredate和 ename升序排列;

SELECT * FROM EMP  ORDER BY HIREDATE,ENAME;

6.查詢emp表,要求先按照JOB降序,再按照SAL升序排列;

SELECT * FROM EMP ORDER BY JOB DESC,SAL;
  • 7.按員工崗位升序排列且除經理外其他工種小寫,經理排在第一位
SELECT * FROM (SELECT CASE WHEN JOB='MANAGER' THEN  'MANAGER' ELSE LOWER(JOB) END "JOB" FROM EMP) ORDER BY JOB ASC; 

↑↓

SELECT CASE WHEN JOB='MANAGER' THEN 'MANAGER' ELSE LOWER(JOB) END FROM EMP ORDER BY JOB ASC; 
  • 8.查詢工資超過1500的部門平均工資
SELECT DEPTNO,AVG(SAL) FROM EMP WHERE SAL>1500 GROUP BY DEPTNO;

9.查詢30號部門和10號部門的平均工資及人數

SELECT DEPTNO,AVG(SAL),COUNT(*) FROM EMP GROUP BY DEPTNO HAVING DEPTNO=10 OR DEPTNO=30 IN (10,30);

↑↓

SELECT DEPTNO,AVG(SAL),COUNT(*) FROM EMP WHERE DEPTNO IN(10,30) GROUP BY DEPTNO;

10.查詢平均工資超過1500的部門的平均工資及最高最低工資差

SELECT DEPTNO,AVG(SAL),MAX(SAL)-MIN(SAL) FROM EMP GROUP BY DEPTNO HAVING AVG(SAL)>1500;

11.查出平均薪資超過800的部門和崗位型別及其平均薪資和最高薪資

SELECT DEPTNO,JOB,AVG(SAL),MAX(SAL) FROM EMP GROUP BY DEPTNO,JOB HAVING AVG(SAL)>800;
    • 12.查詢工資在1000到3000之間,按有獎金和沒有獎金分組,求薪資合計以及平均薪資,按平均薪資升序排列,加一列資料:欄位名 獎金分類 內容:有獎金 無獎金
SELECT SUM(SAL),
       AVG(SAL),
       CASE
         WHEN COMM IS NOT NULL THEN
          '有獎金'
         ELSE
          '無獎金'
       END AS "獎金分類"
  FROM EMP
 WHERE SAL BETWEEN 1000 AND 3000
 GROUP BY CASE
            WHEN COMM IS NOT NULL THEN
             '有獎金'
            ELSE
             '無獎金'
          END
 ORDER BY 2;

集合

對於資料集合進行操作,一般包含 UNION/ UNION ALL INTERSECT MINUS

並集

兩個sql查詢語句,將兩個資料聚合併到一個表中,宇段名以第一個查詢語句為主

應用:

SELECT * FROM EMP 
UNION
SELECT * FROM DEPT;


在這裡插入圖片描述
←會去重

SELECT * FROM EMP 
UNION ALL
SELECT * FROM DEPT;


在這裡插入圖片描述
←不會去重

思考:什麼叫做以第一個查詢語句為主?

SELECT EMPNO FROM EMP
UNION 
SELECT MGR FROM EMP;


在這裡插入圖片描述

SELECT EMPNO FROM EMP
UNION 
SELECT ENAME FROM EMP;

——報錯:表示式必須具有與對應表示式相同的資料型別

總結:兩個查詢語句的顯示列數應當一致,且欄位的資料型別應當一致,且查詢的表的列應當從數量上和資料型別上一致

注意:UNION預設按照第一列排序
而union all不會預設排序

交集

兩個sql查詢語句,求兩個集合中共有的部分,宇段名以第一個查詢語句為主

語法:

SELECT EMPNO FROM EMP WHERE SAL=800 OR SAL=1600
INTERSECT
SELECT EMPNO FROM EMP WHERE SAL=800;

↑↓

SELECT EMPNO FROM EMP WHERE SAL IN(800,1600) AND SAL=1600;

注意:交集預設按照第一列排序

差集

兩個sql查詢語句,將第一個資料聚合中含有第二個資料集合的資料去除,欄位名以第一個查詢語句為主

SELECT EMPNO FROM EMP WHERE SAL=800 OR SAL=1600
MINUS
SELECT EMPNO FROM EMP WHERE SAL=800;

注意:'減數’與’被減數’是有區別的

習題:
1.查詢部門編號是10,20的員工資訊

SELECT * FROM EMP WHERE DEPTNO IN(10,20);
SELECT * FROM EMP WHERE DEPTNO=10 OR DEPTNO=20;
SELECT * FROM EMP WHERE DEPTNO=10 UNION SELECT * FROM EMP WHERE DEPTNO=20;

2.查詢員工資訊,職位是 CLERK或者 SALESMAN或者 ANALYST

SELECT * FROM EMP WHERE JOB=‘CLERK’ OR JOB=‘SALESMAN’ OR JOB=‘ANALYST’;
SELECT * FROM EMP WHERE JOB IN(‘CLERKL’,‘SALESMAN’,‘ANALYST’);
SELECT * FROM EMP WHERE JOB=‘CLERK’
UNION SELECT * FROM EMP WHERE JOB IN(‘SALESMAN’)
UNION SELECT * FROM EMP WHERE JOB=‘ANALYST’;

3.查詢薪資是800,950的員工資訊

SELECT * FROM EMP WHERE SAL= 800 OR SAL =950;
SELECT * FROM EMP WHERE SAL IN(800,950);
SELECT * FROM EMP WHERE SAL=800 UNION SELECT * FROM EMP WHERE SAL=950;

4.查詢上級編號7902、7698的員工資訊

SELECT * FROM EMP WHERE MGR=7902 OR MGR=7698;
SELECT * FROM EMP WHERE MGR IN(7902,7698);
SELECT * FROM EMP WHERE MGR=7902 UNION SELECT * FROM EMP WHERE MGR=7698;

5.員工工資不是800和1600的員工資訊

SELECT * FROM EMP WHERE SAL <>800 AND SAL<>1600;
SELECT * FROM EMP WHERE SAL NOT IN (800,1600);
SELECT * FROM EMP
MINUS
SELECT * FROM EMP WHERE SAL IN(800,1600);

6.查詢員工薪資為1000到3000的員工資訊

SELECT * FROM EMP WHERE SAL BETWEEN 1000 AND 3000;
SELECT * FROM EMP WHERE 1000<=SAL AND SAL<=3000;
SELECT * FROM EMP
MINUS
SELECT * FROM EMP WHERE SAL<1000 OR SAL>3000;

7.查詢員工編號在7500到7700之間的員工

SELECT * FROM EMP WHERE EMPNO BETWEEN 7500 AND 7700;
SELECT * FROM EMP WHERE EMPNO>=7500 AND EMPNO<=7700;
SELECT * FROM EMP
MINUS
SELECT * FROM EMP WHERE EMPNO<7500 OR EMPNO>7700;

8.查詢姓名是以A開頭的、薪資在1000到1500之間的員工

SELECT * FROM EMP WHERE ENAME LIKE ‘A%’ AND SAL BETWEEN 1000 AND 1500;
SELECT * FROM EMP WHERE ENAME LIKE ‘A%’ AND SAL<=1500 AND SAL>=1000;

9.查詢薪資在1000-3000之間,並且部門編號是10或者20

SELECT * FROM EMP WHERE DEPTNO IN(10, 20) AND SAL BETWEEN 1000 AND 3000;

10.查詢(部門編號是20並且工作崗位是 CLERK的員工),或者薪資大於3000的員工

SELECT * FROM EMP WHERE (DEPTNO=20 AND JOB=‘CLERK’) OR SAL>3000;

11.查詢沒有員工的部門編號

SELECT DISTINCT DEPTNO FROM DEPT WHERE DEPTNO NOT IN (SELECT DISTINCT DEPTNO FROM EMP);

↑↓

SELECT DISTINCT DEPTNO FROM DEPT
MINUS 
SELECT DISTINCT DEPTNO FROM EMP;

12.查詢30號部門中有,10部門沒有的崗位名稱

SELECT DISTINCT  JOB FROM EMP WHERE DEPTNO=30 AND JOB NOT IN(SELECT JOB FROM EMP WHERE DEPTNO=10);

↑↓

SELECT DISTINCT JOB FROM EMP WHERE DEPTNO=30
MINUS 
SELECT DISTINCT JOB FROM EMP WHERE DEPTNO=10;
  1. 如何將M表在這裡插入圖片描述
    轉化成N表 ?在這裡插入圖片描述

SELECT ENAME "姓名",
       SUM(CASE
             WHEN COURSE = '語文' THEN
              SCORE
             ELSE
              NULL(預設的,可以不寫)
           END) _ "語文",
       SUM(CASE
             WHEN COURSE = '數學' THEN
              SCORE
             ELSE
              NULL
           END) "數學",
       SUM(CASE
             WHEN COURSE = '英語' THEN
              SCORE
             ELSE
              NULL
           END) "英語"
  FROM M
 GROUP BY ENAME
 ORDER BY 姓名DESC;

14.如何將N表
在這裡插入圖片描述

轉化成M表?
在這裡插入圖片描述

SELECT 姓名 "ENAME",'語文' "COURSE",語文 "SCORE" FROM N
UNION ALL
SELECT 姓名 ,'數學' "COURSE",數學 "SCORE" FROM N
UNION ALL
SELECT 姓名 ,'英語' "COURSE",英語 "SCORE" FROM N
ORDER BY 姓名 DESC;

↑利用了查詢常量
SELECT ‘A’ FROM EMP;

在這裡插入圖片描述
和union all的結合