为了让我们的客户能够存储他们自己的一些数据以及我们的数据结构,我创建了两个额外的表:
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);
sid
和bid
是标识数据所属客户的系统值。 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_column
,external_data
中的给定:row_id
都有一个条目,这样就可以了。但我想确保每个column
始终有一行,即使没有给定:row_id
的数据。有没有办法用一个查询来做到这一点?
答案 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来说是必不可少的。