1. 程式人生 > >★★★ oracle外連線,Oracle中Left Outer Join和外關聯(+)的區別

★★★ oracle外連線,Oracle中Left Outer Join和外關聯(+)的區別

【原】Oracle中Left Outer Join和外關聯(+)的區別 2008-03-23 16:22:37

Oracle的left join中on和where的區別 2009-09-28 15:20

今天遇到一個求某月所有天數的統計結果,如果某日的結果是0也需要顯示出來,即:

日期                  交易次數   交易金額

2009-4-01           1              10

2009-4-02           2              20

2009-4-03           0              0

2009-4-04           5              50

....

一開始我用的左連線,用on做為兩表關聯條件,用where作為過濾條件,但是發現0的資料根本不顯示,後來把where關鍵字去掉,把過濾條件都放到on裡,問題解決,網上一搜,找到了答案:

資料庫在通過連線兩張或多張表來返回記錄時,都會生成一張中間的臨時表,然後再將這張臨時表返回給使用者

      在使用left jion時,on和where條件的區別如下:

1、 on條件是在生成臨時表時使用的條件,它不管on中的條件是否為真,都會返回左邊表中的記錄

2、where條件是在臨時表生成好後,再對臨時表進行過濾的條件。這時已經沒有left join的含義(必須返回左邊表的記錄)了,條件不為真的就全部過濾掉

       假設有兩張表:

表1 tab1:

id size

1 10

2 20

3 30

表2 tab2:

size name

10    AAA

20    BBB

20    CCC


兩條SQL:
1、select * form tab1 left join tab2 on (tab1.size = tab2.size) where tab2.name=’AAA’
2、select * form tab1 left join tab2 on (tab1.size = tab2.size and tab2.name=’AAA’)

第一條SQL的過程:

1、中間表
on條件:
tab1.size = tab2.size

tab1.id    tab1.size    tab2.size     tab2.name

1               10                   10               AAA

2               20                   20               BBB

2               20                   20               CCC

3               30                   (null)           (null)

2、再對中間表過濾
where 條件:
tab2.name=’AAA’

tab1.id       tab1.size        tab2.size     tab2.name

1                  10                  10              AAA

第二條SQL的過程:

1、中間表
on條件:
tab1.size = tab2.size and tab2.name=’AAA’
(條件不為真也會返回左表中的記錄)

tab1.id      tab1.size         tab2.size       tab2.name

1               10                     10                   AAA

2               20                    (null)                (null)

3               30                    (null)                (null)

     其實以上結果的關鍵原因就是left join,right join,full join的特殊性,不管on上的條件是否為真都會返回left或right表中的記錄,full則具有left和right的特性的並集。 而inner jion沒這個特殊性,則條件放在on中和where中,返回的結果集是相同的。

多表連結 Left join

一個我寫的例項:其中多表連線,一共連線了3個表。使用聚集函式SUM,用到了GROUP BY

SELECT a.[UserID],b.[Name],sum (c.[Money]+c.[Bank])as TotalMoney
FROM Table1 a(nolock)
 
LEFTJOIN Table2 b(nolock) on a.[UserID]= b.[UserID] 
LEFTJOIN Table3 c(nolock) ON b.[UserID]=c.[UserID] 

WHERE  a.[UserID]= b.[UserID]and a.[UserID]= c.[UserID]and a.[Time]>='2005-01-01'AND a.[Time]<='2006-12-31' 

GROUPBY a.[UserID],b.[Name]

ORDERBY a.[Time]DESC


優化一下

================================================================================
Left Join 語法:

SELECT a.[UserID],b.[Name],sum (c.[Money]+c.[Bank])as TotalMoney
FROM Table1 a(nolock)
LEFTJOIN Table3 c(nolock) ON a.[UserID]=c.[UserID],  Table2 b(nolock) 

WHERE  a.[UserID]= b.[UserID]and a.[Time]>='2005-01-01'AND a.[Time]<='2006-12-31' 

GROUPBY a.[UserID],b.[Name]

ORDERBY a.[Time]DESC select*from
table1   
leftjoin   table2   on   條件1   
leftjoin   table3   on
   條件2   
leftjoin   table4   on
   條件3  
where   條件4


GROUP BY 說明:

group by 

    在select 語句中可以使用group by 子句將行劃分成較小的組,然後,使用聚組函式返回每一個組的彙總資訊,另外,可以使用having子句限制返回的結果集。group by 子句可以將查詢結果分組,並返回行的彙總資訊Oracle 按照group by 子句中指定的表示式的值分組查詢結果。

   在帶有group by 子句的查詢語句中,在select 列表中指定的列要麼是group by 子句中指定的列,要麼包含聚組函式

   select max(sal),job emp group by job;
   (注意max(sal),job的job並非一定要出現,但有意義)

   查詢語句的select 和group by ,having 子句是聚組函式唯一出現的地方,在where 子句中不能使用聚組函式。

  select deptno,sum(sal) from emp where sal>1200 group by deptno having sum(sal)>8500 order by deptno;

  當在gropu by 子句中使用having 子句時,查詢結果中只返回滿足having條件的組。在一個sql語句中可以有where子句和having子句。having 與where 子句類似,均用於設定限定條件
 
  where 子句的作用是在對查詢結果進行分組前,將不符合where條件的行去掉,即在分組之前過濾資料,條件中不能包含聚組函式,使用where條件顯示特定的行。
  having 子句的作用是篩選滿足條件的組,即在分組之後過濾資料,條件中經常包含聚組函式,使用having 條件顯示特定的組,也可以使用多個分組標準進行分組。

  查詢每個部門的每種職位的僱員數
  select deptno,job,count(*) from emp group by deptno,job;

Oracle表連線方式(2008-08-06 16:29:54)

Oracle 的左連線和右連線


PL-SQL中,左連線和右連線以如下方式來實現
檢視如下語句:
SELECT emp_name, dept_name FORM Employee, Department   WHERE Employee.emp_deptid(+) = Department.deptid
此SQL文使用了右連線,即“(+)”所在位置的另一側為連線的方向,右連線說明等號右側的所有記錄均會被顯示,
無論其在左側是否得到匹配,也就是說上例中無論會不會出現某個部門沒有一個員工的情況,這個部門的名字都會在查詢結果中出現。

反之:
SELECT emp_name, dept_name FORM Employee, Department WHERE Employee.emp_deptid = Department.deptid(+)
則是左連線,無論這個員工有沒有一個能在Department表中得到匹配的部門號,這個員工的記錄都會被顯示

一般的相等連線:
select * from a, b where a.id = b.id;
這個就屬於內連線。
 
對於外連線 :
Oracle 中可以使用“(+) ”來表示,9i可以使用LEFT/RIGHT/FULL OUTER JOIN 
 
LEFT OUTER JOIN:左外關聯 
SELECT e.last_name, e.department_id, d.department_name 
FROM employees e 
LEFT OUTER JOIN departments d 
ON (e.department_id = d.department_id); 
等價於 
SELECT e.last_name, e.department_id, d.department_name 
FROM employees e, departments d 
WHERE e.department_id=d.department_id(+) 
結果為:所有員工及對應部門的記錄,包括沒有對應部門編號department_id的員工記錄。 
 
RIGHT OUTER JOIN:右外關聯 
SELECT e.last_name, e.department_id, d.department_name 
FROM employees e 
RIGHT OUTER JOIN departments d 
ON (e.department_id = d.department_id); 
等價於 
SELECT e.last_name, e.department_id, d.department_name 
FROM employees e, departments d 
WHERE e.department_id(+)=d.department_id 
結果為:所有員工及對應部門的記錄,包括沒有任何員工的部門記錄。 
 
FULL OUTER JOIN:全外關聯 
SELECT e.last_name, e.department_id, d.department_name 
FROM employees e 
FULL OUTER JOIN departments d 
ON (e.department_id = d.department_id); 
結果為:所有員工及對應部門的記錄,包括沒有對應部門編號department_id的員工記錄和沒有任何員工的部門記錄。

外關聯是Oracle資料庫的專有語句

Left Outer Join則是SQL-92的標準語句

通常認為這兩個SQL是可以等效的,但還是有些細微的差別。

一般說來,外關聯的等值條件等效於Left Outer Join中的on語句;兩個where中其他語句是一樣的。

但是Left Outer Join中的其他條件(非表連線)出現在On關鍵詞後面還是出現在Where關鍵詞後面是不一樣的,這樣的語句很難用外關聯進行同義轉義

下面我們先看一個測試資料,和一個測試案例

建立一個部門表和員工表

CREATE TABLE departments

(

depIDNUMBER(38,0),

depName VARCHAR2(20),

delFlag NUMBER(1,0)

);

CREATE TABLE employees

(

empIDNUMBER(38,0),

empName VARCHAR2(20),

depIDNUMBER(38,0),

delFlag NUMBER(1,0)

);

INSERT INTO departments VALUES(1,'Finacle',0);

INSERT INTO departments VALUES(2,'Marketing',0);

INSERT INTO departments VALUES(3,'HR',1);

INSERT INTO departments VALUES(4,'IT',0);

INSERT INTO employees VALUES(1,'wbq',1,0);

INSERT INTO employees VALUES(2,'czh',2,0);

INSERT INTO employees VALUES(3,'chh',1,0);

INSERT INTO employees VALUES(4,'wal',2,0);

INSERT INTO employees VALUES(5,'ddd',3,0);

COMMIT;

以下為測試例子

--列出部門ID3的部門和員工資訊,不管該部門是否有員工

SELECT d.depID,d.depName,e.empName

FROM departments d

LEFT OUTER JOIN employees e

ON d.depID = e.depID

WHERE d.depID =3

ORDER BY d.depID;

--和上面等效

SELECT d.depID,d.depName,e.empName

FROM departments d, employees e

WHERE d.depID = e.depID(+)

AND d.depID =3

ORDER BY d.depID;

--該例子可能不是很恰當,d.depID=3表示首先進行全左連線,然後查詢depID=3的紀錄,如果該部門中找不到對應的員工,則該部門員工則為NULL,同時都顯示部門資訊。

SELECT d.depID,d.depName,e.empName d.delflag

FROM departments d

LEFT OUTER JOIN employees e

ON d.depID = e.depID AND e.depID=3

ORDER BY d.depID;

--和上面不等價,差別在於能夠找到無對應員工的部門和有對應員工的部門,卻找不到該部門無員工的部門。

SELECT d.depID,d.depName,e.empName,d.delflag

FROM departments d, employees e

WHERE d.depID = e.depID(+)

AND (e.depID=3 or e.depID is NULL)

ORDER BY d.depID;

相關推薦

★★★ oracle連線,OracleLeft Outer Join關聯(+)的區別

【原】Oracle中Left Outer Join和外關聯(+)的區別 2008-03-23 16:22:37 Oracle的left join中on和where的區別 2009-09-28 15:20 今天遇到一個求某月所有天數的統計結果,如果某日的結果是0

Inner Join, Left Outer JoinAssociation的區別

outer 驗證 sta alt str 圖片 信息 class 能夠 測試用的CDS視圖的源代碼,第8行用Inner Join連接TJ02T, 後者存放了所有系統狀態的ID和描述。 Inner Join測試結果:對於那些在TJ02T裏沒有維護描述信息的狀態,它們不會出現

OCP-1Z0-051 第131題 LEFT OUTER JOINRIGHT OUTER JOIN的用法

View the Exhibit and examine the structure of the PRODUCT, COMPONENT, and PDT_COMP tables. In PRODUCT table, PDTNO is the primary key. In COMPONENT table,

Pythonthreading的joinsetDaemon的區別及用法

退出 mon comment ber .cn 結束 必須 用法 方法 Python多線程編程時經常會用到join()和setDaemon()方法,基本用法如下: join([time]): 等待至線程中止。這阻塞調用線程直至線程的join() 方法被調用中止-正常退出或者

Pythonthreading的joinsetDaemon的區別及用法[例子]

Python多執行緒程式設計時,經常會用到join()和setDaemon()方法,今天特地研究了一下兩者的區別。 1、join ()方法:主執行緒A中,建立了子執行緒B,並且在主執行緒A中呼叫了B.join(),那麼,主執行緒A會在呼叫的地方等待,直到子執行

oracle中右表有過濾條件的left outer join

oracle中left outer join就是以左表作為基表來進行連線操作,連線的結果中一定會涵蓋基表中所有的列,即使有某些列與右表找不到匹配關係。如下分別是city表和stds表中的資料截圖:  

db2left()函數right()函數對應oracle的substr()函數

itl sql sel div 都是 db2 class () tle DB2 LEFT、RIGHT函數 語法:LEFT(ARG,LENGTH)、RIGHT(ARG,LENGTH) LEFT、RIGHT函數返回ARG最左邊、右邊的LENGTH個字符串,ARG可以是CHAR或

JOIN連線LEFT OUTER JOIN

外聯接。外聯接可以是左向外聯接、右向外聯接或完整外部聯接。  在 FROM 子句中指定外聯接時,可以由下列幾組關鍵字中的一組指定: LEFT JOIN 或 LEFT OUTER JOIN。  左向外聯接的結果集

hiveleft/right join on連線and與where的使用問題

很多同學在進行表關聯的時候,and和where的使用有時候分不清,在這裡實操記錄下。 建立人員資訊表並寫入資料 create table tmp.userinfo(id string,name string,age string,dept string); insert into tmp.userinf

SparkSqljoin的實現( inner joinleft outer join,right outer join,full outer join

Join是SQL語句中的常用操作,良好的表結構能夠將資料分散在不同的表中,使其符合某種正規化,減少表冗餘、更新容錯等。而建立表和表之間關係的最佳方式就是Join操作。 SparkSQL作為大資料領域的SQL實現,自然也對Join操作做了不少優化,今天主要看一下在SparkS

Hibernateleft outer join

首先,最簡單的是一對多的連線,比如: select student from Teacher t join t.students student where student.... 如果是多對一呢?這裡有隱式和顯示的區別(上面的一對多的情況屬於隱式連線)。可以像下面這樣 s

db2與hiveleft joinleft outer join區別

db2中inner join沒有左右之分,outer join有左右之分,其目的在於需要確定以誰為主表; hive中不支援left join,支援left outer join; hive中left semi join作用類似於SQL中的in,以右表中的欄位(key )進

SQLleft outer join,inner join,right outer join用法詳解

      使用關係代數合併資料 1 關係代數 合併資料集合的理論基礎是關係代數,它是由E.F.Codd於1970年提出的。 在關係代數的形式化語言中: ?          用表、或者資料集合表示關係或者實體。 ?          用行表示元組。 ?          用列表示屬性。 關係代數包含以下8個

left outer join的on不起作用

oci join microsoft nbsp mysq soft sel asp msdn left outer join的on不起作用 https://msdn.microsoft.com/zh-cn/library/ms177634.aspx?f=255&am

Linq表連接大全(INNER JOINLEFT OUTER JOIN、RIGHT OUTER JOIN、FULL OUTER JOIN、CROSS JOIN)

iar value fsm wdcp esc max als tla plc 轉載http://www.cnblogs.com/shenqiboy/p/3260105.html 我們知道在SQL中一共有五種JOIN操作:INNER JOIN、LEFT OUTER JOIN、

SQLinner joinouter joincross join區別

tab 卡爾 ner 進行 from oss sql right ble 缺省情況下是inner join,開發中使用的left join和right join屬於outer join,另外outer join還包括full join.下面我通過圖標讓大家認識它們的區別。現

oracledrop、deletetruncate的區別

win style 刪除數據 oracl 數據庫 不能 存在 表空間 結構 oracle中可以使用drop、delete和truncate三個命令來刪除數據庫中的表, 1. delete和truncate都是刪除表中的內容而不能刪除表的結構,而drop則是刪除表的結構和內容

Detected cartesian product for LEFT OUTER join

carte pro 卡爾 tween led 12px new mce style spark做表連接的時候出現這個錯誤, Exception in thread "main" org.apache.spark.sql.AnalysisException: Detect

Mysql Left/Right join on後面andwhere條件查詢的差異-Mysql SQL運算子是有優先順序

一、Mysql中Left/Right join on後面and和where條件查詢的差異 1、建兩張測試表,一張商戶定義表、一張商戶操作狀態明細表 1)商戶定義表 CREATE TABLE hope.merchant (  MERCHANT_id varchar(100) COLLATE ut

系統設計時應儘量避免出現left outer join, right outer join

今天蓋爾找我優化一條SQL,SQL如下: SELECT DISTINCT b.organ_id, c.company_name as organ_name, a.distri