2013-10-28 171 views
3

也許我錯過了一些愚蠢的,但...
我在M-到-M的關係三個表:MySQL的左連接返回空結果

CREATE TABLE tbl_users (
    usr_id  INT NOT NULL AUTO_INCREMENT , 
    usr_name  VARCHAR(64) NOT NULL DEFAULT '' , 
    usr_surname VARCHAR(64) NOT NULL DEFAULT '' , 
    usr_pwd  VARCHAR(64) NOT NULL , 
    usr_level  INT(1) NOT NULL DEFAULT 0, 
    PRIMARY KEY (usr_id) 
) ENGINE = InnoDB; 


CREATE TABLE tbl_houses (
    house_id  INT NOT NULL AUTO_INCREMENT , 
    city   VARCHAR(100) DEFAULT '' , 
    address  VARCHAR(100) DEFAULT '' , 
    PRIMARY KEY (house_id) 
) ENGINE = InnoDB; 

CREATE TABLE tbl_users_houses (
    user_id  INT NOT NULL , 
    house_id  INT NOT NULL , 
    INDEX user_key (user_id), 
    FOREIGN KEY (user_id) REFERENCES tbl_users(usr_id) 
    ON DELETE CASCADE 
    ON UPDATE CASCADE, 
    INDEX house_key (house_id) , 
    FOREIGN KEY (house_id) REFERENCES tbl_houses(house_id) 
    ON DELETE CASCADE 
    ON UPDATE CASCADE 
) ENGINE = InnoDB; 

到鏈路表我有兩個記錄:

user_id house_id 
    1   1 
    1   2 

現在,嘗試選擇所有的房子:

select * from tbl_houses AS H 
    left join tbl_users_houses AS UH on H.house_id = UH.house_id 
where UH.user_id = 2; 

爲什麼我沒有數據而不是所有房屋?

回答

6

因爲該行的任何用戶:

where UH.user_id = 2; 

這隻有在UH.user_id非空的情況下才是真實的,因此它有效地排除了在UH中有沒有匹配行的房屋的任何情況,這是使用LEFT JOIN的一點。

如果你希望所有的房屋,以及UH數據,其中有一個匹配,使用:

select * from tbl_houses AS H 
    left join tbl_users_houses AS UH on H.house_id = UH.house_id and UH.user_id = 2; 
+0

天啊!這很尷尬!我必須修改我的SQL手冊! :-P非常感謝! – Barzo

2

你的WHERE子句指定

UH.user_id = 2 

,如果你將其更改爲H.user_id = 2會發生什麼?

爲了給這個(所有房屋的USER_ID = 2):

select * from tbl_houses AS H 
    left join tbl_users_houses AS UH on H.house_id = UH.house_id 
where H.user_id = 2; 

或者,如果你希望所有的房子不管和user_ID的數據= 2,其中它存在於tbl_User_houses試試這個:

select * from tbl_houses AS H 
    left join tbl_users_houses AS UH on H.house_id = UH.house_id and UH.user_id = 2; 
1

Becasue你有一個ID爲2

0

假設你的問題:「爲什麼我沒有得到任何數據,而不是所有的房子?」意味着您想知道爲什麼當用戶表在外連接的內側上處於打開狀態時沒有獲得所有用戶,這是因爲您將謂詞條件放在連接(在where子句中)之後而不是在連接條件中。這有效地將連接轉換爲內部連接。將其更改爲:

select * from tbl_houses H 
    left join tbl_users_houses UH 
     on uh.house_id = h.house_id 
     and UH.user_id = 2; 

在處理完所有連接後應用where子句的條件。此時,來自外部聯接外部表的行的值將全部具有空值,因此對這樣的值的任何謂詞條件都會導致這些行被刪除。