2

2つのテーブルとがtbl_fooあり、これらのテーブルをon-clauseでtbl_bar結合したいと思います。tbl_foo.foo_id = tbl_bar.foo_idただし、それぞれtbl_bar.baz_idに1つの行が必要です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);
4

3 に答える 3

3

mwigdalh が言ったように、与えられたテーブルでその出力を達成する方法はありません。別の 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        |
+--------+--------+--------+------------+

より現実に近い例で何らかのコンテキストを提供すると、目的の結果を達成するまったく異なる出力があることがわかる場合があります。

于 2012-04-04T13:30:42.530 に答える
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」を「person」と「car」に置き換えると、このクエリは基本的に、すべての人がすべての車を所有していることを示しています。これは事実かもしれませんが、「所有権」の多対多テーブル (バー) には表示されません。

于 2012-04-04T13:53:29.747 に答える
0

漠然と、ここからそこに行くことはできません。baz_idからの対応する行がない for 行を指定する結果を求めていますtbl_bar。この場合、欠落しているデータを構築する方法はまったくありません。

スキーマが正しくないか、 で行が見つからない場合にカスタムのデフォルト ロジックが必要ですtbl_bar

于 2012-04-04T13:26:45.197 に答える