Java 10---SELECT多表查詢
阿新 • • 發佈:2018-12-22
導讀
1.多表聯查
2.多表連線的方式
3.集合運算子
多表聯查
語法:
SELECT 欄位
FROM 表1,表2,...,表n
WHERE 條件(拼接條件,其它條件)
ORDER BY;
笛卡爾積:
一張表的笛卡爾積是它本身
兩張表的笛卡爾積的結果是:行數相乘,列數相加
三張表的笛卡爾積:m*n*k行
多表聯查:避免笛卡爾積
注意:
1.執行流程 FROM,笛卡爾積的結果->WHERE,篩選出主外來鍵值相等的->SELECT,篩選出列 ->ORDER BY,排序 2.多表查詢時,取主外來鍵值相等的記錄才是正確的 拼接條件個數:表的個數-1 3.可以給表取別名,不能三心二意,一旦起別名,就只能使用別名 4.在多表聯查時,儘量給每一個列都加表字首
eg1:查詢出每個員工的編號,名字,對應的部門名 SELECT s_emp.id,first_name,name FROM s_emp,s_dept WHERE dept_id=s_dept.id; SELECT e.id,e.first_name,d.name FROM s_emp e,s_dept d WHERE e.dept_id = d.id; eg2:查詢薪資高於1000的員工的編號,名字,薪資,部門名 SELECT e.id,e.first_name,e.salary,d.name FROM s_emp e,s_dept d WHERE e.dept_id = d.id AND e.salary>1000; eg3:查詢客戶的名字,及其對應的銷售的名字 SELECT c.name,e.first_name FROM s_customer c,s_emp e WHERE c.sales_rep_id=e.id; eg4:查詢每個員工的名字,對應的部門名,對應的區域名 SELECT e.first_name,d.name as dname,r.name as rname FROM s_emp e,s_dept d,s_region r WHERE e.dept_id=d.id AND d.region_id=r.id; eg5:查詢3號區域所有的員工編號,員工名,區域名,並按照員工名升序排序 SELECT e.id,e.first_name,r.name FROM s_emp e,s_dept d,s_region r WHERE e.dept_id=d.id AND d.region_id=r.id AND r.id=3 ORDER BY e.first_name ASC;
多表連線的方式
等價連線,連線條件是=,常用的方式,以上都是 不等價連線,連線條件不是=, eg: CREATE TABLE s_salgrade ( losal number(4), hisal number(4), grade char(1) ); INSERT INTO s_salgrade VALUES(0,999,'D'); INSERT INTO s_salgrade VALUES(1000,1499,'C'); INSERT INTO s_salgrade VALUES(1500,1999,'B'); INSERT INTO s_salgrade VALUES(2000,2500,'A'); COMMIT; eg6:查詢每個員工的id,名字,薪資,薪資等級 SELECT e.id,e.first_name,e.salary,g.grade FROM s_emp e,s_salgrade g WHERE e.salary BETWEEN g.losal AND g.hisal;
外連線,基於等價連線的,
左外連線:結果包含,等價連線的結果和左表不匹配的資料
語法:oracle中有特色語法,接近等價連線
特色語法:
SELECT 欄位
FROM 表1,表2
WHERE 表1.列=表2.列(+);
注意:WHERE中=左邊的表稱為左表,=右邊的表稱為右表
標準語法:
SELECT 欄位
FROM 左表 LEFT [OUTER] JOIN 右表
ON 連線條件
WHERE 其它篩選條件;
右外連線:結果包含,等價連線的結果和右表不匹配的資料
右外可以改成左外,只要會一個就可以了
特色語法:
SELECT 欄位
FROM 表1,表2
WHERE 表1.列(+)=表2.列;
注意:WHERE中=左邊的表稱為左表,=右邊的表稱為右表
標準語法:
SELECT 欄位
FROM 左表 RIGHT [OUTER] JOIN 右表
ON 連線條件
WHERE 其它篩選條件;
全外連線(全連線):結果包含,等價連線的結果和左表,右表不匹配的資料
標準語法: 沒有特色語法
SELECT 欄位
FROM 左表 FULL [OUTER] JOIN 右表
ON 連線條件
WHERE 其它篩選條件;
eg7: 查詢"每個"客戶的名字,及其對應的銷售的名字,左外
SELECT c.name,e.first_name
FROM s_customer c,s_emp e
WHERE c.sales_rep_id=e.id(+);
查詢"每個"客戶的名字,及其對應的銷售的名字,右外
SELECT c.name,e.first_name
FROM s_customer c,s_emp e
WHERE e.id(+)=c.sales_rep_id;
全外測試語句:
SELECT c.name,e.first_name
FROM s_customer c FULL OUTER JOIN s_emp e
ON e.id=c.sales_rep_id;
內連線:等價於等價連線
語法:
SELECT 欄位
FROM 左表 [INNER] JOIN 右表
ON 連線條件
WHERE 其它篩選條件;
SELECT c.name,e.first_name
FROM s_customer c INNER JOIN s_emp e
ON e.id=c.sales_rep_id;
自連線:自己跟自己連線
如果外來鍵列引用了自己表的主鍵列或唯一列,此時可能用到自連線
eg:查詢每個員工的名字,及其領導的名字
SELECT e1.first_name,e2.first_name AS manager_name
FROM s_emp e1,s_emp e2
WHERE e1.manager_id=e2.id(+);
eg:查詢薪資高於其領導薪資的員工名,員工薪資,對應的領導名,領導薪資
SELECT e1.first_name,e1.salary,e2.first_name AS m_name,
e2.salary AS m_salary
FROM s_emp e1,s_emp e2
WHERE e1.manager_id=e2.id
AND e1.salary>e2.salary;
集合運算子
集合運算子,
rownum:行號(重點)
union:並集
union all:並
intersect:交集
minus:減
UNION:並集,
包含兩個結果集全部的結果,重複的只保留一份,
會按照結果集第一列排序升序排序
SELECT id,first_name
FROM s_emp
WHERE id<15;
SELECT id,first_name
FROM s_emp
WHERE id>5;
eg:
SELECT first_name,id
FROM s_emp
WHERE id<15
UNION
SELECT first_name,id
FROM s_emp
WHERE id>5;
UNION ALL:把兩個結果集的結果加起來,不會排序,不會去重
eg:
SELECT first_name,id
FROM s_emp
WHERE id<15
UNION ALL
SELECT first_name,id
FROM s_emp
WHERE id>5;
INTERSECT:交集,取兩個結果集中都有的結果,會排序,去重
eg:
SELECT first_name,id
FROM s_emp
WHERE id<15
INTERSECT
SELECT first_name,id
FROM s_emp
WHERE id>5;
MINUS:減,第一個結果集減去(第一個和第二個都有的),會去重,排序
eg:
SELECT first_name,id
FROM s_emp
WHERE id<15
MINUS
SELECT first_name,id
FROM s_emp
WHERE id>5;
rownum:
代表結果集中的行號
是一個偽列,並不是真實存在的
可以用來實現分頁
注意:結果集中的行號永遠從1開始
rownum條件只要不是從1開始,就是沒有結果的
執行流程:
FROM->WHERE->SELECT,結果集確定,行號就確定了->ORDER
現有行號,再排序的
SELECT rownum,id,first_name
FROM s_emp
WHERE id>5;
取使用者表的前五個使用者:
SELECT rownum,id,first_name
FROM s_emp
WHERE rownum<6;
取使用者表的第6~10個使用者:
SELECT rownum,id,first_name
FROM s_emp
WHERE rownum>5 AND rownum<11; 錯誤
SELECT rownum,id,first_name
FROM s_emp
WHERE rownum<11
MINUS
SELECT rownum,id,first_name
FROM s_emp
WHERE rownum<6; 正確的