我有两个表,tbl_foo
和tbl_bar
,我想在on-clause中将这些表与tbl_foo.foo_id = tbl_bar.foo_id
连接起来。但是,对于每个tbl_bar.baz_id
,每个tbl_foo.foo_id
应该有一行(即使tbl_bar
中没有此类条目)。我该如何撰写此类查询?
下面有关于架构和我想要的结果的更多信息。
foo_id
和baz_id
。tbl_baz
。+--------+--------+--------+------------+
| bar_id | baz_id | foo_id | some_field |
+--------+--------+--------+------------+
| 1 | 101 | 1 | foo |
| 2 | 101 | 2 | bar |
| 3 | 101 | 3 | baz |
| NULL | 101 | 4 | bin |
| 4 | 102 | 1 | foo |
| NULL | 102 | 2 | bar |
| 5 | 102 | 3 | baz |
| NULL | 102 | 4 | bin |
+--------+--------+--------+------------+
+--------+------------+
| foo_id | some_field |
+--------+------------+
| 1 | foo |
| 2 | bar |
| 3 | baz |
| 4 | bin |
+--------+------------+
+--------+--------+--------+
| bar_id | baz_id | foo_id |
+--------+--------+--------+
| 1 | 101 | 1 |
| 2 | 101 | 2 |
| 3 | 101 | 3 |
| 4 | 102 | 1 |
| 5 | 102 | 3 |
+--------+--------+--------+
+--------+
| baz_id |
+--------+
| 101 |
| 102 |
+--------+
CREATE TABLE tbl_foo (
foo_id INT,
some_field VARCHAR(255),
PRIMARY KEY (foo_id)
);
INSERT INTO tbl_foo VALUES
(1, 'foo'),
(2, 'bar'),
(3, 'baz'),
(4, 'bin');
CREATE TABLE tbl_bar (
bar_id INT,
baz_id INT,
foo_id INT,
PRIMARY KEY (bar_id, baz_id),
FOREIGN KEY (baz_id) REFERENCES tbl_baz (baz_id),
FOREIGN KEY (foo_id) REFERENCES tbl_foo (foo_id)
);
INSERT INTO tbl_bar VALUES
(1, 101, 1),
(2, 101, 2),
(3, 101, 3),
(4, 102, 1),
(5, 102, 3);
CREATE TABLE tbl_baz (
baz_id INT,
PRIMARY KEY (baz_id)
);
INSERT INTO tbl_baz VALUES
(101),
(102);
答案 0 :(得分:3)
+--------+--------+--------+------------+
| bar_id | baz_id | foo_id | some_field |
+--------+--------+--------+------------+
| 1 | 101 | 1 | foo |
| 2 | 101 | 2 | bar |
| 3 | 101 | 3 | baz |
| NULL | *101*| 4 | bin |
| 4 | 102 | 1 | foo |
| NULL | *102*| 2 | bar |
| 5 | 102 | 3 | baz |
| NULL | *102*| 4 | bin |
+--------+--------+--------+------------+
如果你在一个更贴近现实世界的例子中提供一些背景信息,可能会发现总共有一个不同的输出可以达到你想要的结果。
答案 1 :(得分:1)
你可能正在寻找这样的查询:
<强>更新强>
基于新的tbl_baz:
select y.bar_id, x.baz_id, x.foo_id, x.some_field
from (
select a.foo_id, a.some_field, b.baz_id
-- Cross foo_id with all baz_id
from tbl_foo as a, tbl_baz as b
) as x
-- Get the bar_id where it exists for each foo_id/baz_id combo
left join tbl_bar as y on x.foo_id = y.foo_id
and x.baz_id = y.baz_id
order by x.baz_id, x.foo_id
这是基于这样的假设:您希望查看每个baz_id的每个foo_id,而不管多对多表中的内容是什么。
示例您可能不想要这个的原因,或者可能想要更新您的多对多表:
如果我们用“人”和“汽车”代替“foo”和“baz”,这个问题基本上就是说每个人都拥有每辆车。情况可能如此,但肯定没有在“所有权”多对多表格(bar)中表示。
答案 2 :(得分:0)
含糊不清,你不能从这里到达那里。您要求的结果为baz_id
中没有相应行的行指定tbl_bar
。在这种情况下,根本无法构建缺失的数据。
您的架构不正确,或者在tbl_bar
中找不到行的情况下需要一些自定义默认逻辑。