sql >> データベース >  >> RDS >> PostgreSQL

すべてが配列されているPostgreSQL

    結合テーブルが適切な方法に従っており、一意の複合キーが定義されていると仮定します。つまり、行の重複を防ぐための制約がある場合は、次の簡単なクエリのようになります。

    select conversation_id from conversations_users where user_id in (1, 2)
    group by conversation_id having count(*) = 2
    

    最後の2は、user_idのリストの長さであることに注意してください。 user_idリストの長さが変更された場合は、明らかに変更する必要があります。結合テーブルに重複が含まれていないと想定できない場合は、パフォーマンスをいくらか犠牲にして、「count(*)」を「count(distinctuser_id)」に変更してください。

    このクエリは、たとえであっても、指定されたすべてのユーザーを含むすべての会話を検索します 会話には追加のユーザーも含まれます。

    正確にとの会話のみが必要な場合 指定されたユーザーのセットの場合、1つのアプローチは、以下のようにwhere句でネストされたサブクエリを使用することです。最初と最後の行は元のクエリと同じであり、真ん中の2行だけが新しいことに注意してください。

    select conversation_id from conversations_users where user_id in (1, 2)
       and conversation_id not in
       (select conversation_id from conversations_users where user_id not in (1,2))
    group by conversation_id having count(*) = 2
    

    同様に、データベースでサポートされている場合は、差セット演算子を使用できます。 Oracle構文の例を次に示します。 (PostgresまたはDB2の場合、キーワード「マイナス」を「例外」に変更します。)

    select conversation_id from conversations_users where user_id in (1, 2)
      group by conversation_id having count(*) = 2
    minus
      select conversation_id from conversations_users where user_id not in (1,2)
    

    優れたクエリオプティマイザはすべき 最後の2つのバリエーションは同じように扱いますが、特定のデータベースで確認してください。たとえば、Oracle 11GR2クエリ・プランは、マイナス演算子を適用する前に2セットの会話IDをソートしますが、最後のクエリのソート・ステップをスキップします。したがって、行数、コア、キャッシュ、インデックスなどの複数の要因に応じて、どちらのクエリプランも高速になる可能性があります。



    1. 自分自身を再帰的に呼び出すmysqlストアドプロシージャ

    2. 2022年に練習しなければならないSQLクエリインタビューの質問トップ30

    3. PDO+MySQLおよび壊れたUTF-8エンコーディング

    4. 多次元OLAPCUBEとは何ですか?3次元以上のキューブの例を示します