「3 つのテーブルに参加する方法」に関する 100 の異なる投稿を読みましたが、自分のやりたいことを実行できないようです。私がオンラインで見つけた例とは異なるようです。これは単純に 2 つの左結合です。
tests
-----
id
name
platformA <<-- boolean, platformA supports test?
platformB
platformX
testgroups <<-- tuple (testid,platid) is unique
----------
testid <<-- matches 'id' in 'tests' table above
platid <<-- matches id in 'platforms' table below
grouptype
platforms
---------
id
name <<-- corresponds to column name 'platform?' in 'tests'
テストグループにそのようなエントリがあるかどうかに関係なく、platformA が 1 である「テスト」の各テスト名に対して正確に 1 つの行を持つ結果が必要なので、テストグループをテストに結合したままにします。私が理解できないのは、プラットフォームテーブルを関与させる方法です。これが私が持っているもので、うまくいきません:
select tests.name, testgroups.grouptype from tests
left join testgroups on (tests.id = testgroups.testid)
where tests.platformA = 1;
これは、testgroup が複数の testid = 2 (platid = ?? ごとに 1 つ) を持つことができるため、機能しません。タプルは一意であることが保証されていますが、どちらの列もそれ自体では保証されていません。したがって、tests.name ごとに、各プラットフォームの行が表示されます。プラットフォーム名 (たとえば、platformA) で制限する必要がありますが、テーブル testgroups ではアクセスできません。したがって、プラットフォーム名の代わりに platid を知っていれば、これを行うことができます。
select tests.name, testgroups.grouptype from tests
left join testgroups on (tests.id = testgroups.testid and testgroups.platid = 27)
where tests.platformA = 1;
platformA だけが必要なのはわかっていますが、その ID が (上記の例では) 27 であることは、プラットフォーム テーブルで調べないとわかりません。これをクエリに組み込むにはどうすればよいですか? 私は多くの組み合わせを試しましたが、どれもうまく機能しません。これは私がうまくいくと思ったものの1つの例です:
select tests.name, testgroups.grouptype from tests, platforms
left join testgroups on (tests.id = testgroups.testid and platforms.name = 'platformA')
where tests.platformA = 1;
これは不正な構文のようです。複数の左結合も試しましたが、うまくいきません。
答えが欲しいのですが、しばらくの間頭を悩ませていたので、なぜそれが機能するのかについて少し説明したいと思います。
ありがとう、デビッド
====更新====
@Marc はほぼ正しいと思いますが、testgroups.platid がそのプラットフォームのデータを持つ行によって出力が制限されます。
彼の答えを使用して、完全なクエリを提供する私の試みは次のとおりです。
select tests.name, testgroups.grouptype from tests
left join testgroups on (tests.id = testgroups.testid)
left join platforms on (testgroups.platid = platforms.id)
where tests.platformA = 1 and (platforms.name = 'platformA' or platforms.id is null);