sql >> Database teknologi >  >> RDS >> PostgreSQL

Find rækker, der har samme værdi i én kolonne og andre værdier i en anden kolonne?

Dette er et tilfælde af relationel opdeling . Vi har samlet et arsenal af teknikker under dette relaterede spørgsmål:

Den særlige vanskelighed er at udelukke yderligere brugere. Der er grundlæggende 4 teknikker.

Jeg foreslår LEFT JOIN / IS NULL :

SELECT cu1.conversation_id
FROM        conversation_user cu1
JOIN        conversation_user cu2 USING (conversation_id)
LEFT   JOIN conversation_user cu3 ON cu3.conversation_id = cu1.conversation_id
                                 AND cu3.user_id NOT IN (3,32)
WHERE  cu1.user_id = 32
AND    cu2.user_id = 3
AND    cu3.conversation_id IS NULL;

Eller NOT EXISTS :

SELECT cu1.conversation_id
FROM   conversation_user cu1
JOIN   conversation_user cu2 USING (conversation_id)
WHERE  cu1.user_id = 32
AND    cu2.user_id = 3
AND NOT EXISTS (
   SELECT 1
   FROM   conversation_user cu3
   WHERE  cu3.conversation_id = cu1.conversation_id
   AND    cu3.user_id NOT IN (3,32)
   );

Begge forespørgsler ikke afhænge af en UNIQUE begrænsning for (conversation_id, user_id) , som måske er på plads eller ikke. Det betyder, at forespørgslen endda fungerer, hvis user_id 32 (eller 3) er opført mere end én gang for den samme samtale. Du ville få duplikerede rækker i resultatet, men skal anvende DISTINCT eller GROUP BY .
Den eneste betingelse er den, du formulerede:

Revideret forespørgsel

forespørgslen, du linkede til i kommentaren ville ikke virke. Du glemte at udelukke andre deltagere. Bør være noget i stil med:

SELECT *  -- or whatever you want to return
FROM   conversation_user cu1
WHERE  cu1.user_id = 32
AND    EXISTS (
   SELECT 1
   FROM   conversation_user cu2
   WHERE  cu2.conversation_id = cu1.conversation_id 
   AND    cu2.user_id = 3
   )
AND NOT EXISTS (
   SELECT 1
   FROM   conversation_user cu3
   WHERE  cu3.conversation_id = cu1.conversation_id
   AND    cu3.user_id NOT IN (3,32)
   );

Hvilket ligner de to andre forespørgsler, bortset fra at det ikke returnerer flere rækker, hvis user_id = 3 er forbundet flere gange.



  1. array eller liste ind i Oracle ved hjælp af cfprocparam

  2. Base64-kodet streng til simpel sql-injektion

  3. ORA-00054:ressource optaget og anskaffelse med NOWAIT angivet eller timeout udløbet

  4. MySQL - vælg data fra databasen mellem to datoer