sql >> Databáze >  >> RDS >> PostgreSQL

Připojte se ke čtyřem stolům zahrnujícím LEFT JOIN bez duplikátů

Máte dvě LEFT JOINS :

  • První levé spojení se může připojit k více řádkům z solved . Řekněme, že 'jane' a 'luke' vyřešili úkol.
  • Druhé levé připojení se může připojit pouze k uživatelům jménem 'luke' ('luke' v podmínce připojení!).

Stále máte obě řádky, 'jane' se prostě nezobrazuje, podmínka spojení ji odfiltruje, ale LEFT JOIN stejně zachová řádek ve výsledku a připojí hodnoty NULL.

Pomocí závorek můžete dosáhnout toho, po čem toužíte a [INNER] JOIN místo LEFT JOIN mezi solved a users . Manuál:

V případě potřeby použijte k určení pořadí vnoření závorky. Při absenci závorek JOIN s hnízdo zleva doprava.

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;
  • Použití názvu tabulky users místo vyhrazeného slova user .

  • Za předpokladu, že users.name je definováno jako jedinečné nebo můžete mít více uživatelů pojmenovaných 'luke'.

  • Pokud (task.id, users.id) v solved je definováno jako UNIQUE nebo PRIMARY KEY , nepotřebujete DISTINCT vůbec.

Výsledný dotaz je nejen správný, ale také rychlejší.

Verze SqlAlchemy výše uvedeného dotazu: (přispěl @van)
To předpokládá, že Category , Task a User jsou mapované třídy, zatímco solved je instancí Table (pouze asociační tabulka, jak je ukázáno v příkladu kódu 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. Jak vybrat datum bez času v SQL

  2. Jak vytvořit dočasnou tabulku v SQL?

  3. Jak vytvořit omezení cizího klíče pomocí ON UPDATE CASCADE v SQL Server - SQL Server / Výukový program TSQL, část 79

  4. Jak se dostanete k limitům 8060 bajtů na řádek a 8000 na hodnotu (varchar, nvarchar)?