PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

PostgreSQL, wo alles im Array ist

Angenommen, die Join-Tabelle folgt bewährten Verfahren und hat einen eindeutigen zusammengesetzten Schlüssel definiert, d. h. eine Einschränkung, um doppelte Zeilen zu verhindern, dann sollte so etwas wie die folgende einfache Abfrage ausreichen.

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

Es ist wichtig zu beachten, dass die Zahl 2 am Ende die Länge der Liste der user_ids ist. Das muss sich natürlich ändern, wenn sich die Länge der user_id-Liste ändert. Wenn Sie nicht davon ausgehen können, dass Ihre Join-Tabelle keine Duplikate enthält, ändern Sie „count(*)“ in „count(distinct user_id)“, was möglicherweise zu Leistungseinbußen führt.

Diese Abfrage findet alle Konversationen, die alle angegebenen Benutzer enthalten, selbst wenn die Konversation umfasst auch weitere Benutzer.

Wenn Sie nur Gespräche mit genau wollen die angegebene Gruppe von Benutzern, besteht ein Ansatz darin, eine verschachtelte Unterabfrage in der where-Klausel wie unten zu verwenden. Beachten Sie, dass die erste und die letzte Zeile mit der ursprünglichen Abfrage identisch sind, nur die beiden mittleren Zeilen sind neu.

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

Entsprechend können Sie einen Satzdifferenzoperator verwenden, wenn Ihre Datenbank dies unterstützt. Hier ist ein Beispiel in Oracle-Syntax. (Ändern Sie für Postgres oder DB2 das Schlüsselwort „minus“ in „außer.)

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)

Ein guter Abfrageoptimierer sollte Behandeln Sie die letzten beiden Varianten identisch, überprüfen Sie jedoch zur Sicherheit Ihre spezielle Datenbank. Beispielsweise sortiert der Oracle 11GR2-Abfrageplan die beiden Sätze von Konversations-IDs, bevor der Minusoperator angewendet wird, überspringt jedoch den Sortierschritt für die letzte Abfrage. Daher könnte jeder Abfrageplan in Abhängigkeit von mehreren Faktoren wie der Anzahl der Zeilen, Kerne, Cache, Indizes usw. schneller sein.