3

也许我错过了一些愚蠢的东西,但是......
我有三个 m-to-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

4 回答 4

8

因为这条线:

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;
于 2013-10-28T14:47:22.640 回答
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;
于 2013-10-28T14:46:50.840 回答
1

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

于 2013-10-28T14:47:00.660 回答
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 子句中的条件。此时,来自外连接外侧的表中的行中的值都将包含空值,因此对此类值的任何谓词条件都会导致这些行被消除。

于 2013-10-28T14:48:41.623 回答