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

Policz wiersze po dołączeniu do trzech tabel w PostgreSQL

Aby uprościć logikę, najpierw zagreguj, dołącz później.

Zgadując brakujące szczegóły, to zapytanie podałoby dokładną liczbę, ile razy każdy użytkownik był odwoływany w table1 i table2 odpowiednio dla wszystkich użytkowników :

SELECT *
FROM   users u
LEFT   JOIN (
   SELECT updated_by_id AS id, count(*) AS t1_ct
   FROM   table1
   GROUP  BY 1
   ) t1 USING (id)
LEFT   JOIN (
   SELECT updated_by_id AS id, count(*) AS t2_ct
   FROM   table2
   GROUP  BY 1
   ) t2 USING (id);

W szczególności unikaj wielu relacji 1-n mnożących się nawzajem po połączeniu:

Aby pobrać jednego lub kilku użytkowników tylko, LATERAL dołączania będą szybsze (Postgres 9.3+):

SELECT *
FROM   users u
LEFT   JOIN  LATERAL (
   SELECT count(*) AS t1_ct
   FROM   table1
   WHERE  updated_by_id = u.id
   ) ON true
LEFT   JOIN  LATERAL (
   SELECT count(*) AS t2_ct
   FROM   table2
   WHERE  updated_by_id = u.id
   ) ON true
WHERE  u.id = 100;

Wyjaśnij dostrzeżoną różnicę

Zgłoszona przez Ciebie konkretna niezgodność wynika ze specyfiki FULL OUTER JOIN :

Tak więc otrzymujesz wartości NULL dołączone po odpowiedniej drugiej stronie za brakujące dopasowania. count() nie liczy wartości NULL. Możesz więc uzyskać inny wynik w zależności od tego, czy filtrujesz według u1.id=100 lub u2.id=100 .

To tylko wyjaśnienie, nie potrzebujesz FULL JOIN tutaj. Zamiast tego użyj przedstawionych alternatyw.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Trwała baza danych przy użyciu woluminów Docker

  2. Pole rails, które jest tablicą obiektów JSON?

  3. Getter i setter Pythona poprzez @property w definicji klasy modelu SqlAlchemy:HOWTO

  4. Plan wyjaśniania SQL:co to jest Materialise?

  5. czy możesz używać bibliotek w PL/Perl