このスキーマを考えると:
CREATE TABLE t (
id int,
name varchar(200),
primary key (id)
);
CREATE TABLE t2 (
id int,
name varchar(200),
primary key (id)
);
CREATE TABLE rel (
id1 int,
id2 int,
value int,
primary key (id1, id2),
foreign key (id1) REFERENCES t(id),
foreign key (id2) REFERENCES t2(id)
);
t
との複数の関係を満たす行をクエリするにはどうすればよいt2
ですか? これは十分に簡単に聞こえますが、この場合のベスト プラクティスが何であるかはわかりません。クエリでよりよく説明します。
SELECT t.id, t.name
FROM t
INNER JOIN rel ON (t.id = rel.id1)
INNER JOIN t2 ON (t2.id = rel.id2)
WHERE (rel.id2 = 1 AND rel.value = 1)
上記は、1 つの関係を満たす行を見つける必要がある場合にうまく機能します。でも今:
SELECT t.id, t.name
FROM t
INNER JOIN rel ON (t.id = rel.id1)
INNER JOIN t2 ON (t2.id = rel.id2)
WHERE (rel.id2 = 1 AND rel.value = 1)
AND (rel.id2 = 2 AND rel.value = 2)
2 つのリレーションシップでは、結合された行が 1 つの行に 2 つの異なるリレーションシップを持つことはないため、このクエリは機能しません。したがって、常に0
行が返されます。
私がこれまで使用してきたソリューションは、リレーションからの結果セットでt.id
あるを探しています。IN
SELECT t.id, t.name
FROM t
WHERE (t.id IN (SELECT id1 FROM rel WHERE rel.id2 = 1 AND rel.value = 1))
AND (t.id IN (SELECT id1 FROM rel WHERE rel.id2 = 2 AND rel.value = 2))
これはうまくいきますが、もっと良い方法はありませんか?SQL を書きすぎていて、アイテムごとに 1 つのサブクエリを実行するのは、とても単純なことに対してやり過ぎのように感じます。
これがSQLフィドルです