14

foo、foo2bar、barの3つのテーブルがあります。foo2barは、fooとbarの間の多対多のマップです。内容はこちらです。

select * from foo
+------+
| fid  |
+------+
|    1 |
|    2 |
|    3 |
|    4 |
+------+

select * from foo2bar
+------+------+
| fid  | bid  |
+------+------+
|    1 |    1 |
|    1 |    2 |
|    2 |    1 |
|    2 |    3 |
|    4 |    4 |
+------+------+

select * from bar
+------+-------+------+
| bid  | value | zid  |
+------+-------+------+
|    1 |     2 |   10 |
|    2 |     4 |   20 |
|    3 |     8 |   30 |
|    4 |    42 |   30 |
+------+-------+------+

私が要求したいのは、「zidが30のすべてのfidと値のリストを教えてください」です。

私はすべてのfidに対する答えを期待しているので、結果は次のようになります。

+------+--------+
| fid  | value  |
+------+--------+
|    1 |   null |
|    2 |      8 |
|    3 |   null |
|    4 |     42 |
+------+--------+
4

5 に答える 5

17
SELECT * FROM foo
  LEFT OUTER JOIN (foo2bar JOIN bar ON (foo2bar.bid = bar.bid AND zid = 30))
  USING (fid);

MySQL5.0.51でテスト済み。

これはサブクエリではなく、かっこを使用して結合の優先順位を指定するだけです。

于 2008-12-16T19:39:56.030 に答える
6
SELECT * FROM
        foo LEFT JOIN
        (
        Foo2bar JOIN bar
             ON foo2bar.bid = bar.bid AND zid = 30
        )
        ON foo.fid = foo2bar.fid;

テストされていません

于 2008-12-16T19:36:07.083 に答える
2

それを解決して、あなたはあなたの選択から始めることができます。最終的に表示したくない列は含めないでください。

SELECT foo.fid, bar.value

次に、WHERE句を実行できます。これは、あなたが表現したとおりに表示されます。

SELECT foo.fid, bar.value  
WHERE bar.zid = 30

ここで、中間一致があるかどうかに関係なく、すべてのfidを確認したいので、LEFT JOINを使用して、FROM句で物事を接続するのが難しい部分です。

SELECT foo.fid, bar.value  
FROM foo  
LEFT JOIN foo2bar ON foo.fid = foo2bar.fid  
LEFT JOIN bar ON foo2bar.bid = bar.bid  
WHERE bar.zid = 30
OR bar.zid IS NULL
于 2008-12-16T19:43:06.727 に答える
2

fid = 3の行が返ってこない場合は、サーバーが壊れています。

このコードは、私が望むことを実行するはずです。

SELECT
    F.fid,
    SQ.value
FROM
    dbo.Foo F
LEFT OUTER JOIN
     (
     SELECT F2B.fid, B.value
     FROM dbo.Bar B
     INNER JOIN dbo.Foo2Bar F2B ON F2B.bid = B.bid WHERE B.zid = 30
     ) SQ ON SQ.fid = F.fid

zidが30の2つのバーに関連している場合、fidの2つの値を取り戻すことができることに注意してください。

于 2008-12-16T19:47:55.373 に答える
-1

FWIW、質問は実際には多対多に関するものではありません。これは非常に単純に組合として行うことができます。

SQLの実際の多対多は、CROSSJOINです。

于 2008-12-16T23:00:29.980 に答える