PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Преброяване на редове след свързване на три таблици в PostgreSQL

За да опростите логиката си, първо обединете, присъединете се по-късно.

Отгатвайки липсващи подробности, тази заявка ще ви даде точния брой, колко пъти всеки потребител е бил споменат в table1 и table2 съответно за всички потребители :

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

По-специално, избягвайте множество 1-n релации, които се умножават една друга, когато са обединени:

За да извлечете един или няколко потребители само, LATERAL присъединяванията ще бъдат по-бързи (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;

Обяснете възприеманата разлика

Конкретното несъответствие, за което съобщавате, се дължи на спецификата на FULL OUTER JOIN :

Така че получавате NULL стойности, добавени към съответната друга страна за липсващи съвпадения. count() не отчита NULL стойности. Така че можете да получите различен резултат в зависимост от това дали филтрирате по u1.id=100 или u2.id=100 .

Това е само за обяснение, нямате нужда от FULL JOIN тук. Вместо това използвайте представените алтернативи.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Вмъкнете стойност на полето за диапазон от дати в таблицата на PostgreSQL чрез JDBC

  2. Опитвам се да конструирам PostgreSQL Query за извличане от JSON на текстова стойност в обект, в масив, в обект, в масив, в обект

  3. Рекурсивна заявка със сума в Postgres

  4. Разлика в производителността:условието е поставено в клауза INNER JOIN спрямо WHERE

  5. django получава месец от датата за агрегиране