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

Dołącz do czterech stołów z udziałem LEFT JOIN bez duplikatów

Masz dwa LEFT JOINS :

  • Pierwsze lewe połączenie może dołączyć do wielu wierszy z solved . Powiedz, że „jane” i „luke” rozwiązali zadanie.
  • Drugie lewe dołączenie może dołączyć tylko do użytkowników o nazwie „luke” („luke” w warunku dołączenia!).

Nadal otrzymujesz oba wiersze, 'jane' po prostu nie jest pokazywana, warunek złączenia odfiltrowuje ją, ale LEFT JOIN zachowuje wiersz w wyniku i dodaje wartości NULL.

Możesz osiągnąć to, czego szukasz, używając nawiasów i [INNER] JOIN zamiast LEFT JOIN między solved i users . Instrukcja:

W razie potrzeby użyj nawiasów, aby określić kolejność zagnieżdżania. W przypadku braku nawiasów JOIN gniazdo od lewej do prawej.

SELECT c.name AS cat_name, t.name AS task_name, u.name AS user_name
FROM   task t
JOIN   category c ON cat.id = t.category_id
LEFT   JOIN
      (solved s JOIN users u ON u.id = s.user_id AND u.name = 'luke') ON s.task_id = t.id
ORDER  BY 1, 2, 3;
  • Korzystanie z nazwy tabeli users zamiast zastrzeżonego słowa user .

  • Zakładając, że users.name jest zdefiniowany jako unikalny lub możesz mieć wielu użytkowników o nazwie „luke”.

  • Jeśli (task.id, users.id) w solved jest zdefiniowany UNIQUE lub PRIMARY KEY , nie potrzebujesz DISTINCT w ogóle.

Wynikowe zapytanie jest nie tylko poprawne, ale także szybsze.

Wersja SqlAlchemy powyższego zapytania: (nadesłane przez @van)
Zakłada się, że Category , Task i User są klasami mapowanymi, podczas gdy solved jest instancją Table (tylko tablica asocjacyjna, jak pokazano w przykładzie wiele do wielu):

user_name = 'luke'
q = (session.query(Category.name, Task.name, User.name)
     .select_from(Task)
     .join(Category)
     .outerjoin(
         join(solved, User,
              (solved.c.user_id == User.id) & (User.name == user_name),
         ))
     .order_by(Category.name, Task.name, User.name)
     )


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Wskazówki i porady dotyczące poruszania się po społeczności PostgreSQL

  2. Jak działa make_interval() w PostgreSQL

  3. Dodaj wskaźnik porządkowy do daty w PostgreSQL

  4. Jak określić ostatni dzień poprzedniego miesiąca za pomocą PostgreSQL?

  5. Niestandardowe ZAMÓWIENIE WEDŁUG Wyjaśnienia