MySQL LEFT JOIN返回空结果集

时间:2013-10-28 14:44:59

标签: mysql sql

也许我想念一些愚蠢但是......
我有三个m-m关系表:

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;

为什么我没有数据而不是所有的房子?

4 个答案:

答案 0 :(得分:6)

由于这一行:

where UH.user_id = 2;

仅当UH.user_id为非null时才会出现这种情况,因此它实际上排除了您在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;

答案 1 :(得分: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;

或者,如果你想要所有的房子,并且在tbl_User_houses中存在user_id = 2的数据,请尝试:

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;

答案 2 :(得分:1)

因为您没有ID为2的用户。

答案 3 :(得分: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子句的条件。此时,外连接外侧表中行的值将全部包含空值,因此对这样的值的任何谓词条件都将导致这些行被消除。