2013-05-11 93 views
1
|----------------------------| 
| Tbl_1      | 
|--------------|-------------| 
| id   | name_1  | 
|--------------|-------------| 
| 1   | t_1_rec_1 | 
|--------------|-------------| 

|------------------------------------------------------------| 
| Tbl_2              | 
|-------|--------------|-----------|------------|------------| 
| id | name_2  | tbl_1_id | tbl_3_id | tbl_4_id | 
|-------|--------------|-----------|------------|------------| 
| 1 | t_2_rec_1 | 1   | 1   | 2   | 
| 2 | t_2_rec_2 | 1   | 2   | 1   | 
|-------|--------------|-----------|------------|------------| 

|------------------------| 
| Tbl_3     | 
|----------|-------------| 
| id  | name_3  | 
|----------|-------------| 
| 1  | t_3_rec_1 | 
| 2  | t_3_rec_2 | 
|----------|-------------| 

|----------------------| 
| Tbl_4    | 
|--------|-------------| 
| id | name_4  | 
|--------|-------------| 
| 1  | t_4_rec_1 | 
| 2  | t_4_rec_2 | 
|--------|-------------| 


|--------------------------------------------| 
| Tbl_5          | 
|------|------------|------------|-----------| 
| id | name_5 | tbl_2_id | tbl_6_id | 
|------|------------|------------|-----------| 
| 1 | t_5_rec_1 | 1   | 1   | 
| 2 | t_5_rec_2 | 1   | 2   | 
|------|------------|------------|-----------| 

|----------------------------------| 
| Tbl_6       | 
|-------|------------| 
| id | name_6  | 
|-------|------------| 
| 1 | t_6_rec_1 | 
| 2 | t_6_rec_2 | 
|-------|------------| 

我期待這些結果聯接未返回記錄:內部聯接在左當左加入記錄不存在

t1.name_1 t2.name_2 t3.name_3 t4.name_4 t5.name_5 t6.name_6 

t_1_rec_1 t_2_rec_1 t_3_rec_1 t_4_rec_2 t_5_rec_1 t_6_rec_1 
t_1_rec_1 t_2_rec_1 t_3_rec_1 t_4_rec_2 t_5_rec_2 t_6_rec_2 
t_1_rec_1 t_2_rec_2 t_3_rec_2 t_4_rec_1 

select t1.name_1, t2.name_2, t3.name_3, t4.name_4, t5.name_5, t6.name_6 
from Tbl_1 as t1 
left join Tbl_2 as t2 on t2.id = t1.id 
inner join Tbl_3 as t3 on t2.tbl_3_id = t3.id 
inner join Tbl_4 as t4 on t2.tbl_4_id = t4.id 
left join Tbl_5 as t5 on t5.id = t2.id 
inner join Tbl_6 as t6 on t2.tbl_6_id = t6.id 

但這不起作用!!!!!第三行不返回。將最後一個內連接(Tbl_6)更改爲左連接確實會生成第三行。

我知道Tbl_5和Tbl_6之間的內部連接會導致沒有Tbl_5記錄,但我認爲Tbl_2和Tbl_5之間的左連接會導致Tbl_2和其內部連接的Tbl_3和Tbl_4記錄存在,並且作爲Tbl_1的結果留給Tbl_2,我會得到第三行。

我錯過了什麼? (我不想改變內部連接,因爲我不希望Tbl_5記錄在後面沒有Tbl_6條目)另外,這個查詢是從一個Zend Db類生成的,我需要能夠將任何答案納入,但我想,如果有一個查詢工作正常,或如我所料,那麼我會弄清楚如何讓Zend生成它...

+0

在FROM子句中按順序處理表1,2,5,3,4,6。 – 2013-05-11 21:55:03

回答

0

在SQL(和MySQL)中, inner join,left outer join,right outer joincross join操作都具有相同的優先級。所以,a left join b inner join c(a left join b) inner join c。以相同的方式,算術表達式1 - 2 + 3(1 - 2) + 3而不是1 - (2 + 3)。記住

有了這個,讓我們來看看你的from條款:

from Tbl_1 as t1 
left join Tbl_2 as t2 on t2.id = t1.id 
inner join Tbl_3 as t3 on t2.tbl_3_id = t3.id 
inner join Tbl_4 as t4 on t2.tbl_4_id = t4.id 
left join Tbl_5 as t5 on t5.id = t2.id 
inner join Tbl_6 as t6 on t2.tbl_6_id = t6.id 

第一內聯接是t2.tbl_3_id = t3.id。如果t2表中的t1沒有匹配,則列t2.tbl_3_id將爲NULL。因爲NULL值不匹配,所以效果是將第一個聯接轉換爲內部聯接。

你可以解決這個語法如:

inner join Tbl_3 as t3 on t2.tbl_3_id = t3.id or t2.id is null 

(該NULL比較是t2.id而非t2.tbl_3_id以防該ID可能是一個有效的匹配NULL)

你可以爲後續的連接繼續這個邏輯。

外部連接和內部連接的混合確實不是自動將外部連接轉換爲內部連接。這取決於on條款中的條件。

就我個人而言,我發現遵循連接的語義相當麻煩。我只使用內部聯接或只留下外部聯接編寫幾乎所有的查詢。也就是說,要麼保留所有匹配的行,要麼保留第一個表中的所有行。

如果我想混合連接類型,那麼我有兩個選項。首先是使用子查詢 - 在MySQL中,這可能會導致性能問題。或者,我使用left outer join s,並在where子句中添加條件以實現我想要的邏輯。

+0

嗨戈登。關於你的第一行('在SQL(和MySQL)中......'),我現在沒有材料可以嘗試,但我認爲Oracle的行爲有所不同。 – Sebas 2013-05-12 21:47:51

+0

我試過這個「或t2.id爲空」,並導致所有記錄在Tbl_3中的實際返回的記錄(實際上是我的case中的Tbl_6,但是要檢查內部連接上的null的父ID是否只處理過所有可能的孩子都是真實的,我很可能不得不把它們全部留下來,因爲進一步的思考導致我決定想要看看孩子失蹤的地方。兒童記錄正在退還,讓你想起其他可能奏效的東西,我很想知道這件事。 – StevenHill 2013-05-13 18:56:03