PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Znaleźć wiersze, które mają tę samą wartość w jednej kolumnie i inne wartości w innej kolumnie?

To jest przypadek podziału relacyjnego . W ramach tego pytania zebraliśmy cały arsenał technik:

Szczególną trudnością jest wykluczenie dodatkowych użytkowników. Istnieją zasadniczo 4 techniki.

Proponuję 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;

Lub 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)
   );

Oba zapytania nie zależą od UNIQUE ograniczenie dla (conversation_id, user_id) , który może, ale nie musi, być na miejscu. Oznacza to, że zapytanie działa nawet wtedy, gdy user_id 32 (lub 3) jest wymieniony więcej niż raz dla tej samej rozmowy. chciałbyś uzyskaj jednak zduplikowane wiersze w wyniku i musisz zastosować DISTINCT lub GROUP BY .
Jedyny warunek to ten, który sformułowałeś:

Skontrolowane zapytanie

zapytanie połączone w komentarzu nie zadziała. Zapomniałeś wykluczyć innych uczestników. Powinno być coś takiego:

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)
   );

Co jest podobne do pozostałych dwóch zapytań, z tą różnicą, że nie zwróci wielu wierszy, jeśli user_id = 3 jest połączony wiele razy.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. dlaczego pisze w tabeli zapobiega próżni w innym?

  2. SQL LIMIT z klauzulą ​​WHERE

  3. Wydajność bazy danych:filtrowanie według kolumny a osobna tabela

  4. Jaki jest najskuteczniejszy sposób na przetrwanie tysięcy podmiotów?

  5. PostgreSQL - GROUP BY wartości znacznika czasu?