LEFT JOIN两个表,以便过滤左表数据,但即使左表数据不存在,也会显示正确的表数据

时间:2016-02-11 12:13:34

标签: mysql

为了让我们的客户能够存储他们自己的一些数据以及我们的数据结构,我创建了两个额外的表:

CREATE TABLE external_columns
(
  `id`      INT(11)     PRIMARY KEY   NOT NULL,
  `column`  VARCHAR(30)               NOT NULL,
  `sid`     INT(11)                   NOT NULL,
  `bid`     INT(11)                   NOT NULL,
  `label`   VARCHAR(30)               NOT NULL,
  `table`   VARCHAR(30)               NOT NULL,
  `default` TINYTEXT                  NOT NULL
);

CREATE TABLE external_data
(
    `id`         INT(11) PRIMARY KEY NOT NULL,
    `extcol_id`  INT(11)             NOT NULL,
    `sid`        INT(11)             NOT NULL,
    `bid`        INT(11)             NOT NULL,
    `data`       MEDIUMTEXT          NOT NULL,
    `row_id`     INT(11)             NOT NULL,
    CONSTRAINT `external_data_external_columns_id_fk` 
      FOREIGN KEY (extcol_id) REFERENCES external_columns (id)
);
CREATE UNIQUE INDEX combinedUniqueIndex 
  ON external_data (extcol_id, sid, bid, row_id);

sidbid是标识数据所属客户的系统值。 row_id是指table中引用的表的主键。

要获取某一行的数据,我已经创建了这个准备好的语句:

SELECT `data`.*, `columns`.`column`, `columns`.`default`
FROM `external_columns` as `columns`
  LEFT JOIN `external_data` as `data`
    ON `columns`.`id` = `data`.`extcol_id`
WHERE (
      `columns`.`sid`   = :sid
  AND `columns`.`bid`   = :bid
  AND `data`.`row_id`   = :row_id
  AND `columns`.`table` = :tableName
)

只要对于每个external_columnexternal_data中的给定:row_id都有一个条目,这样就可以了。但我想确保每个column始终有一行,即使没有给定:row_id的数据。有没有办法用一个查询来做到这一点?

1 个答案:

答案 0 :(得分:1)

非常接近,通过在您的WHERE中放置AND data.row_id = :row_id,您已经有效地编写了一个INNER JOIN,因为无效的data.row_id将无法匹配。

您应该将此条件移至LEFT JOIN条件:

   SELECT `data`.*, `columns`.`column`, `columns`.`default`
     FROM `external_columns` as `columns`
LEFT JOIN `external_data` as `data`
       ON `data`.`extcol_id`= `columns`.id
      AND `data`.`row_id`   = :row_id
    WHERE `columns`.`sid`   = :sid
      AND `columns`.`bid`   = :bid
      AND `columns`.`table` = :tableName

个人偏好设置:

不需要WHERE括号,我总是倾向于将JOIN条件中的JOIN条件放在LHS条件中,并使LHS上的JOIN表更加明显。

INNER JOIN没有区别,但对于某些LEFT JOIN来说是必不可少的。