sql >> Database >  >> RDS >> PostgreSQL

Doe mee aan vier tabellen met LEFT JOIN zonder duplicaten

Je hebt twee LEFT JOINS :

  • De eerste linkse join kan deelnemen aan meerdere rijen van solved . Zeg, 'jane' en 'luke' hebben de taak opgelost.
  • De 2e linkse join kan alleen deelnemen aan gebruikers met de naam 'luke' ('luke' in de join-voorwaarde!).

Je krijgt nog steeds beide rijen, 'jane' wordt gewoon niet getoond, de join-voorwaarde filtert haar uit, maar de LEFT JOIN behoudt de rij toch in het resultaat en voegt NULL-waarden toe.

U kunt bereiken wat u wilt door haakjes . te gebruiken en een [INNER] JOIN in plaats van de LEFT JOIN tussen solved en users . De handleiding:

Gebruik zo nodig haakjes om de volgorde van nesten te bepalen. In de afwezigheid van haakjes, JOIN s nest van links naar rechts.

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;
  • Tabelnaam users gebruiken in plaats van het gereserveerde woord user .

  • Ervan uitgaande dat users.name is gedefinieerd uniek of je kunt meerdere gebruikers hebben met de naam 'luke'.

  • Als (task.id, users.id) in solved is gedefinieerd UNIQUE of PRIMARY KEY , je hebt DISTINCT niet nodig helemaal niet.

De resulterende zoekopdracht is niet alleen correct, maar ook sneller.

SqlAlchemy-versie van de bovenstaande zoekopdracht: (bijgedragen door @van)
Dit veronderstelt dat Category , Task en User zijn toegewezen klassen, terwijl solved is instantie van Table (alleen een associatietabel zoals getoond in codevoorbeeld Many to Many):

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. 3 manieren om alle tabellen te retourneren ZONDER een primaire sleutel in SQL Server

  2. Er is een DBConcurrency-uitzondering opgetreden tijdens het bijwerken met behulp van Dataadapter

  3. Postgresql COPY-commando geeft een fout met machtigingen geweigerd

  4. Een kolom toevoegen aan een tabel in SQL