2008-12-05 78 views
4

考慮下表:自聯接查詢

mysql> select * from phone_numbers; 
+-------------+------+-----------+ 
| number  | type | person_id | 
+-------------+------+-----------+ 
| 17182225465 | home |   1 | 
| 19172225465 | cell |   1 | 
| 12129876543 | home |   2 | 
| 13049876543 | cell |   2 | 
| 15064223454 | home |   3 | 
| 15064223454 | cell |   3 | 
| 18724356798 | home |   4 | 
| 19174335465 | cell |   5 | 
+-------------+------+-----------+ 

我試圖找到那些誰擁有家庭電話,但沒有人的細胞。

此查詢的工作:

mysql> select h.* 
    -> from phone_numbers h 
    -> left join phone_numbers c 
    -> on h.person_id = c.person_id 
    -> and c.type = 'cell' 
    -> where h.type = 'home' 
    -> and c.number is null; 
+-------------+------+-----------+ 
| number  | type | person_id | 
+-------------+------+-----------+ 
| 18724356798 | home |   4 | 
+-------------+------+-----------+ 

但是這一次沒有:

mysql> select h.* 
    -> from phone_numbers h 
    -> left join phone_numbers c 
    -> on h.person_id = c.person_id 
    -> and h.type = 'home' 
    -> and c.type = 'cell' 
    -> where c.number is null; 
+-------------+------+-----------+ 
| number  | type | person_id | 
+-------------+------+-----------+ 
| 19172225465 | cell |   1 | 
| 13049876543 | cell |   2 | 
| 15064223454 | cell |   3 | 
| 18724356798 | home |   4 | 
| 19174335465 | cell |   5 | 
+-------------+------+-----------+ 

兩者之間唯一的區別是的h.type = 'home'條件的位置 - 在第一個它在where子句,第二個是on子句的一部分。

爲什麼第二個查詢不會返回與第一個查詢相同的結果?

+0

在第二種情況下,你是否真的做了左連接? – 2008-12-05 15:13:11

+0

幾乎想要這個只是爲了藝術品而竭盡全力解釋情況。 – 2008-12-05 15:35:25

回答

7

在第二個SQL中,條件h.type ='home'是外部連接條件的一部分,並且不是結果上的篩選器。對於h.type ='cell'的所有記錄,條件h.type ='home'爲FALSE,因此沒有找到「匹配」c行 - 因此c.number爲null,這是您唯一的過濾條件(WHERE) 。

在僞代碼的第二次SQL是這樣的:

for each row in phone_numbers h /* Note this is ALL home AND cell phones */ 
    select c.number from phone_numbers c 
    where h.person_id = c.person_id 
    and h.type = 'home' 
    and c.type = 'cell'; 
    if c.number is null (i.e. no row found) 
    display h.* 
    end if 
end loop; 
-2

我不知道這是否會解決的事情或沒有,但...

開始「和」的表述應該是在WHERE子句的一部分,而不是ON子句的一部分。 ON子句應該只有有涉及哪些列用於連接表的語句。

+0

你可以在連接上添加adicional條件。這將作爲在加入前發生的地方 – Sergio 2008-12-05 15:17:56

2

做當左加入我做事這種方式。在連接中,您需要指定將這兩個表實際鏈接在一起的anny字段,以及連接的右側(連接的第二個表)中的任何過濾條件(有一個例外,我馬上就會知道)。從連接的左側(第1個表格)過濾條件應該在where子句中,否則它們會錯誤地影響連接(正如Tony所說的那樣)。唯一一次連接的右側應該位於where子句中的情況是,如果您在該表中查找空值(即,第一個表中但不是第二個中的記錄)。

0
SEL * 
FROM phone_numbers T1 
WHERE typeS='home' AND person_id NOT IN 
(SELECT person_id FROM phone_numbers T2 WHERE T1.person_id=T2.person_id AND typeS='cell') 
0

你可以試試這個查詢,我希望它能爲你工作。

select * from phone_numbers 
where person_id not in (select person_id from phone_numbers where type='cell')