2017-06-15 7 views
0

マシンに接続されたタグのみを使用するテストを選択する必要があります。WHERE(サブクエリ)IN(サブクエリ)は可能ですか?

  • タグは多くのテストからです。 (TagTest連想テーブル)

  • タグがマシンに多くの多くのです。 (TagMachineアソシアティブテーブル)

例:

  • テストタグ[A、B、C]を有しており、マシンが[A、B、D]テストが原因選択されるべきではない持っている場合そのタグはMachineのタグのサブセットではありません。

  • テストタグ[A、B]を有し、マシンは[A、B、D]試験が含まれるべきである持っている場合。

  • テストは、それが常に含まれるべきではタグがない場合。この構造のような

何か作業をする必要があります:

SELECT * 
FROM Test te 
WHERE 
    (SELECT tt.tagId 
    FROM TagTest tt 
    WHERE tt.testId = te.Id) 
IN 
    (SELECT tm.tagId 
    FROM TagMachine tm 
    WHERE tm.machineId = 123) 

しかし、クエリのこの種は可能ですか?そうでない場合は、どのようにして目的の結果を達成することができますか?

+0

[ 'ALL'](https://www.postgresql.org/docs/current/static/functions-subquery.html#FUNCTIONS-SUBQUERY-ALL)演算子を確認してください。 – zerkms

+0

@zerkms ALL演算子も左の値をスカラーにする必要はありませんか? – Noozen

+0

あなたは正しいですが、それは無関係です、私は目を覚まして、効率的に考える準備ができていません。ごめんなさい。 – zerkms

答えて

4

IN()は、それ自体でこれを行うことはできません使用しています。 2つのCTEを作成して一緒に参加することはできますが、やや難しいことです。

代わりに、問題を回避しましょう。代わりにすべて良いのタグに一致するレコードを探しているのは、我々はタグを必要いずれかが欠落しているレコードを探すことができます。質問([A,B,D][A,B,C])の最初の例から、我々はCタグとTestTagたレコードを探しています。この情報を取得すると、サブクエリでこの情報を使用して、のすべての結果を含むTestレコードをすべて除外できます。

だから、まず最初に行うには、対応するTagMachineレコードが不足しているTestTag結果を見つけるために参加除外を使用している:

SELECT tt.testId, tt.tagId 
FROM TestTag tt 
LEFT JOIN TagMachine tm ON tm.machineId = 123 AND tm.tagId = tt.tagId 
WHERE tm.tagId IS NULL 

上記のクエリの結果のいずれかのtestIdの存在はTestとなりますがId不適格こと...しかし、我々は他のすべてのTestの記録をしたいです。今度はDISTINCT testIdに制限し、除外結合、NOT IN()、NOT EXISTS()のいずれかでサブクエリとして使用してください。お好きなところをお選びください:

SELECT * 
FROM Tests 
WHERE Id NOT IN (
    --identify tests hat are missing at least one tag 
    SELECT DISTINCT tt.testId 
    FROM TestTag tt 
    LEFT JOIN TagMachine tm ON tm.machineId = 123 AND tm.tagId = tt.tagId 
    WHERE tm.tagId IS NULL) 
+0

本当に素晴らしい解決策!任意のSQLの方言を使用せずに特定のcontructs。 – edi

3

このクエリは、最初のクエリがスカラ値(つまり1行)を返す場合に可能です。だから、ちょうどINを使ってあなたがしたいことはできません。これを処理するための一つのPostres'yの方法は、配列

WHERE (SELECT ARRAY_AGG(tt.tagId) 
     FROM TagTest tt 
     WHERE tt.testId = te.Id 
    ) <@ 
     (SELECT ARRAY_AGG(tm.tagId) 
     FROM TagMachine tm 
     WHERE tm.machineId = 123 
    ) 
関連する問題