--===========表連接=================
drop table a purge;
drop table b purge;
create table a(
c1 number(4),
c2 varchar(4)
);
create table b(
c3 number(4),
c4 varchar2(10),
c5 number(4) -- 關聯a表
);
insert into a values ( 1,'a');
insert into a values ( 2, '2a');
insert into a values ( 3,'3a');
insert into b values ( 4,'b',1);
insert into b values ( 5, '2b',1);
insert into b values ( 6, '3b',2);
commit;
SQL> select * from a;
C1 C2
------ - ----
1 a
2 2a
3 3a
SQL> select * from b;
C3 C4 C5
----- ------- -------
4 b 1
5 2b 1
6 3b 2
--========= 笛卡爾乘積 :第一個表中的所有行與第二個表中的所有行相連接
-- 笛卡爾集的產生條件:
--省略連接條件
--連接條件無效
select aa.c1,aa.c2 ,bb.c3,bb.c4,bb.c5 from a aa , b bb ; -- 結果: 3 * 3 = 9;
select aa.c1,aa.c2, bb.c3 ,bb.c4 from a aa cross join b bb;-- (SQL 99的寫法)
--查詢每個員工的工號,姓名,工資,部門名和工作地點
select deptno,loc from emp,dept where emp.deptno=dept.deptno order by emp.deptno; -- error deptno 不知道是那個表的列
-- 查詢時列名前,加表名或表別名前輟(如果字段在兩個表中是唯一的可以不加)
select e.deptno,d.loc from emp e,dept d where e.deptno=d.deptno order by e.deptno;--ok
select c1 ,c2 ,c3, c4 from a, b where a.c1 = b.c5;-- ok
--藉此 提下where字句的執行順序, where 子句的執行順序 : 右到左 ,但更深層次的執行順序是oracle的CBD控制的
Select 'ok' From Dual Where 1 / 0 = 1 And 1 = 2; -- ok
Select 'ok' From Dual Where 1 = 2 And 1 / 0 = 1; -- error
--從數據顯示方式來講有:內連接和外連接。
--內連接:只返回滿足連接條件的數據。
--外連接:除了返回滿足連接條的行以外,還返回左(右)表中,不滿足條件的行,稱爲左(右)連接
--內連接
select empno,ename,sal,dname,loc from emp,dept where emp.deptno=dept.deptno; --(Oracle 8i 及以前的寫法)
select aa.c1,aa.c2, bb.c3,bb.c4 ,bb.c4 from a aa, b bb where aa.c1 = bb.c5;
--測試語句: a中的c5, b中的c6都不存在,執行下面的語句出現 bb.c6不存在
select aa.c1,aa.c2, bb.c3,bb.c4 ,bb.c4 from a aa, b bb where aa.c5 = bb.c6;
--內連接(等值連接)的另一種寫法:不支持 as 即使:a as aa 是錯誤的
select aa.c1,aa.c2,aa.b1 , bb.c3,bb.c4 from a1 aa join b1 bb on aa.b1 = bb.c3;-- ok (SQL 99的寫法)
select aa.c1,aa.c2,aa.b1 , bb.c3,bb.c4 from a1 as aa join b1 as bb on aa.b1 = bb.c3;--(不支持 as )
--內連接的執行順序:
-- on t1.c1 = t2.c2; t1驅動,t2匹配(t1匹配,t2驅動結果一樣)
--1.從t1讀取一條記錄,如c1的值r1
--2.根據c1的值到t2表中進行匹配記錄,需要編列t2表(第一條記錄開始).
----如t2的值r2等於r1.表示兩條記錄能否匹配上。t1的r1和t2的r2組合起來.
----作爲結果集的一條記錄,否則檢測t2的下一條記錄.
--3.按照方法2一次將t2表所有的記錄檢測一遍,只要匹配就放入結果集中.
--4.從t1表中讀取第二條記錄,依次重複2,3.產生最終的結果集.
-- 如果內連接有多個記錄需要匹配 ,用and連接 on t1.c1 = t2.c1 and t1.c2 = t2.c2;
--左外連接
SELECT table1.column, table2.column FROM table1, table2 WHERE table1.column = table2.column(+);
-- 說明:我們認爲 a是驅動表, b是匹配表
select aa.c1,aa.c2,bb.c3 ,bb.c4 from a aa left join b bb on aa.c1 = bb.c5;--(SQL 99的寫法)
--執行順序
--1.從a讀取一條記錄,如c1的值r1
--2.根據c1的值到b表中進行匹配記錄,需要編列b表(第一條記錄開始).
--- 如果c5的值r2等於r1.表示兩條記錄能否匹配上。a的c1,c2 和 b的c3,c4 組合起來.作爲結果---集的一條記錄,否則檢測b的下一條記錄.
---按照方法2一次將b表所有的記錄檢測一遍,只要匹配就放入結果集中.
-- 3.如果 a.的r1記錄在b中找不到任何匹配的記錄,b表中模擬一條null記錄 與a 表中的r1組合起來,放入結果集中.
-- 4.從a表中讀取第二條記錄,依次重複2,3.產生最終的結果集.
--右外連接
-- " + " 在那邊 那邊就是匹配表.即aa是匹配表
SELECT table1.column, table2.column FROM table1, table2 WHERE table1.column(+) = table2.column;
select aa.c1,aa.c2,bb.c3,bb.c4 from a aa, b bb where aa.c1(+) = bb.c5; -- (Oracle 8i 及以前的寫法)
select aa.c1,aa.c2,bb.c3 ,bb.c4 from a aa right join b bb on aa.c1 = bb.c5;--(SQL 99的寫法)
--執行分析同上
--全連接(滿連接):結果集= 內連接的結果 + 兩個表中不匹配的記錄
select aa.c1,aa.c2,bb.c3 ,bb.c4 from a aa full join b bb on aa.c1 = bb.c5;--(SQL 99的寫法)
-- Notice:
-- 如果想增加過濾條件 用 on xxx and xx = xx;
select aa.c1,aa.c2,bb.c3 ,bb.c4 from a aa lef join b bb on aa.c1 = bb.c5 and bb.c3 = 6;
--執行順序:
-- 1.先進行on, and 進行過濾.
-- 2. join , on 連接.
-- 3.select結果集
-- 如果想對最終的結果增加過濾,用where字句
select aa.c1,aa.c2,bb.c3 ,bb.c4 from a aa lef join b bb on aa.c1 = bb.c5 where aa.c1 != 1;
--執行順序:
-- 1.先進行on進行過濾.
-- 2. join , on 連接.
-- 3.where過濾
-- 4select結果集
--綜合
select aa.c1,aa.c2,bb.c3 ,bb.c4 from a aa lef join b bb on aa.c1 = bb.c5 and bb.c3 = 5 where aa.c1 != 1;
--執行順序:
-- 1.先進行on,and 進行過濾.
-- 2. join , on 連接.
-- 3.where過濾
-- 4select結果集
參考:樂沙彌的世界