加入/合并两个表,即兴创作/弥补“缺失”条目

时间:2012-04-04 13:16:11

标签: mysql sql database missing-data

我有两个表,tbl_footbl_bar,我想在on-clause中将这些表与tbl_foo.foo_id = tbl_bar.foo_id连接起来。但是,对于每个tbl_bar.baz_id,每个tbl_foo.foo_id应该有一行(即使tbl_bar中没有此类条目)。我该如何撰写此类查询?

下面有关于架构和我想要的结果的更多信息。

  • 修改:每行必须包含foo_idbaz_id
  • 修改2 :在下方添加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        |
+--------+--------+--------+------------+

表:tbl_foo

+--------+------------+
| foo_id | some_field |
+--------+------------+
|      1 | foo        |
|      2 | bar        |
|      3 | baz        |
|      4 | bin        |
+--------+------------+

表:tbl_bar

+--------+--------+--------+
| bar_id | baz_id | foo_id |
+--------+--------+--------+
|      1 |    101 |      1 |
|      2 |    101 |      2 |
|      3 |    101 |      3 |
|      4 |    102 |      1 |
|      5 |    102 |      3 |
+--------+--------+--------+

表:tbl_baz

+--------+
| baz_id |
+--------+
|    101 |
|    102 |
+--------+

SQL架构

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);

3 个答案:

答案 0 :(得分:3)

像pwigdalh所说的那样,没有办法用给定的表来实现那个输出。如果有另一张巴兹表,那就有办法了。问题是,下面突出显示的记录基本上是从空气中拉出来的,毫无意义。你可以很容易地在每一个中加上“meh”,输出也会很有意义。

+--------+--------+--------+------------+
| 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中找不到行的情况下需要一些自定义默认逻辑。