PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

PostgreSQL où tout dans le tableau

En supposant que la table de jointure respecte les bonnes pratiques et qu'une clé composée unique soit définie, c'est-à-dire une contrainte pour empêcher les lignes en double, alors quelque chose comme la requête simple suivante devrait suffire.

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

Il est important de noter que le chiffre 2 à la fin correspond à la longueur de la liste des user_ids. Cela doit évidemment changer si la liste user_id change de longueur. Si vous ne pouvez pas supposer que votre table de jointure ne contient pas de doublons, remplacez "count(*)" par "count(distinct user_id)" au détriment des performances.

Cette requête trouve toutes les conversations qui incluent tous les utilisateurs spécifiés même si la conversation inclut également des utilisateurs supplémentaires.

Si vous voulez uniquement des conversations avec exactement l'ensemble d'utilisateurs spécifié, une approche consiste à utiliser une sous-requête imbriquée dans la clause where comme ci-dessous. Notez que la première et la dernière ligne sont identiques à la requête d'origine, seules les deux lignes du milieu sont nouvelles.

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

De manière équivalente, vous pouvez utiliser un opérateur de différence d'ensemble si votre base de données le prend en charge. Voici un exemple dans la syntaxe Oracle. (Pour Postgres ou DB2, remplacez le mot-clé "moins" par "sauf.)

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)

Un bon optimiseur de requêtes devrait traitez les deux dernières variantes de la même manière, mais vérifiez auprès de votre base de données particulière pour être sûr. Par exemple, le plan de requête Oracle 11GR2 trie les deux ensembles d'ID de conversation avant d'appliquer l'opérateur moins, mais ignore l'étape de tri pour la dernière requête. Ainsi, l'un ou l'autre des plans de requête peut être plus rapide en fonction de plusieurs facteurs tels que le nombre de lignes, de cœurs, de cache, d'index, etc.