多行函數
--作用域多行記錄,返回一個值
No |
名稱 |
類型 |
描述 |
1 |
EMPNO |
NUMBER(4) |
編號:四位數 |
2 |
ENAME |
VARCHAR2(10) |
姓名:10位數字符 |
3 |
JOB |
VARCHAR2(9) |
職位 |
4 |
MGR |
NUMBER(4) |
領導編號:領導也是公司員工 |
5 |
HIREDATE |
DATE |
入職日期 |
6 |
SAL |
NUMBER(7,2) |
基本工資,兩位小數,五位整數,共七位 |
7 |
COMM |
NUMBER(7,2) |
年終獎 |
8 |
DEPTNO |
NUMBER(2) |
員工所在部門編號 |
圖1-1(emp員工表)
分組函數:作用於多行,返回一個值。
l 統計記錄數count(*);注:該函數忽略null值;
l 最小值查詢min();
l 最大查詢max();
l 查詢平均值avg();
l 求和函數sum();
Group by 可以按指定的列將數據分成若個組,然后對組內數據進行多行函數統計。
Eg:查詢每個部門的人數:select deptno,count(*) from emp group by deptno;
Eg:查詢每個部門的平均工資:select deptno,avg(sal) from emp group by deptno;
- 如使用分組函數,sql只能將group by 分組條件字段和分組函數查詢出來,不能有其他字段。
Eg:select deptno,job,avg(sal) from emp group by deptno;--錯誤
Eg:select deptno,job,avg(sal) from emp group by deptno,job;--正確
- 如使用分組函數,不使用group by 的字段,只可以查詢出分組函數的值;
Eg:select avg(sal) from emp;
過濾分組數據 having
Eg:查詢出部門平均工資大於2000的部門,用having和where都可以實現:
Select deptno,avg(sal) from emp group by deptno having avg(sal)>2000;
Select * from (Select deptno,avg(sal) sal from emp group by deptno )where sal>2000;
Eg:查詢部門員工工資大於1500的部門平均工資:
Select deptno,avg(sal) from emp where sal>1500 group by deptno;
多表查詢
--作用域多行記錄,返回一個值
NO |
名稱 |
類型 |
描述 |
1 |
DEPTNO |
NUMBER(2) |
表示部門編號,由兩位數字組成 |
2 |
DNAME |
VARCHAR2(14) |
部門名稱,最多由14個字符組成 |
3 |
LOC |
VARCHAR2(13) |
部門所在位置 |
圖1-1部門表(dept)
No |
名稱 |
類型 |
描述 |
1 |
EMPNO |
NUMBER(4) |
編號:四位數 |
2 |
ENAME |
VARCHAR2(10) |
姓名:10位數字符 |
3 |
JOB |
VARCHAR2(9) |
職位 |
4 |
MGR |
NUMBER(4) |
領導編號:領導也是公司員工 |
5 |
HIREDATE |
DATE |
入職日期 |
6 |
SAL |
NUMBER(7,2) |
基本工資,兩位小數,五位整數,共七位 |
7 |
COMM |
NUMBER(7,2) |
年終獎 |
8 |
DEPTNO |
NUMBER(2) |
員工所在部門編號 |
圖1-2(emp員工表)
什么是多表查詢
l 一個語句需要顯示多張表的數據,則必須應用到多表查詢的操作。
什么是笛卡爾積?
l 數學概念中:集合的關系運算(集合所有關系組合)
用sql實現笛卡爾積:select * from emp e,dept d order by e.empno,e.deptno;
解決笛卡爾積無效數據問題----(內連接:
- 隱式內連接:from A,b where A.關聯字段=B.關聯字段
- 顯式內連接:from A inner join B on a.關聯字段=b.關聯字段):
select * from emp e,dept d where e.deptno = d.deptno;--隱式
select * from emp e inner join dept d on e.deptno = d.deptno;--顯式
總結
l 內連接要求兩張表的數據都滿足要求才可以顯示這條數據。
l 問題:有部門沒員工。關聯查詢要顯示部門信息?----外連接
外連接(在Oracle中有一種特殊寫法:)
- 左外連接:以左表為基准,左表有數據則全部顯示,右表無數據則顯示Null
From B表 left join A on a.關聯字段=b.關聯字段
- 右外連接:以右表為基准,右表有數據則全部顯示,左表無數據則顯示Null
From a表 right join b on a.關聯字段=b.關聯字段
- 外連接(在Oracle中有一種特殊寫法),已左連接為例
FROM A,B WHERE A.關聯字段(+)=b.關聯字段--建議不要用這種寫法,因為不通用
自查詢
- 左外連接:以左表為基准,左表有數據則全部顯示,右表無數據則顯示Null
Eg:查出員工姓名、職位、領導姓名:select * from emp e,emp m where e.mgr = m.empno;
問題:沒有領導的員工信息就沒有了。
解決:加上左連接
Select * from emp e left join emp m on e.mgr = m.empno;
為什么建議使用left join 、right join、inner join on?
- 首先對於外連接而言OARACLE特有的(+)寫法不通用,只針對oracle。
- Left join on 、right join on 、 inner join on 結構更加清晰,調試sql時比較容易。
- (+)部分主次表,而Left join on 、right join on 、 inner join on有明顯的主次之分。