Dans SQL Server, je crée une vue qui montre si un logging dans la table CONTACTS a certaines balises dans une table différente TAGS.
C'est ma requête:
SELECT DISTINCT contacts.ID, contacts.NAME, IIF(tags.tag = 'A', 1, 0) as A, IIF(tags.tag = 'B', 1, 0) as B, IIF(tags.tag = 'C', 1, 0) as C, IIF(tags.tag = 'D', 1, 0) as D FROM contacts LEFT JOIN TAGS ON contacts.ID = TAGS.CONTACT_ID
Je voudrais les résultats comme ceci:
ID NAME ABCD ------------------------------------ 1 BOB 1 0 0 1 1 Charlie 1 0 1 0
mais je reçois
ID NAME ABCD ------------------------------------ 1 BOB 1 0 0 0 1 BOB 0 0 0 1 1 Charlie 1 0 0 0 1 Charlie 0 0 1 0
Doit être quelque chose que je néglige, mais je ne peux pas le find.
Utilisez le group by
:
SELECT c.ID, c.NAME, MAX(CASE WHEN t.tag = 'A' THEN 1 ELSE 0 END) as A, MAX(CASE WHEN t.tag = 'B' THEN 1 ELSE 0 END) as B, MAX(CASE WHEN t.tag = 'C' THEN 1 ELSE 0 END) as C, MAX(CASE WHEN t.tag = 'D' THEN 1 ELSE 0 END) as D FROM contacts c LEFT JOIN TAGS t ON c.ID = t.CONTACT_ID GROUP BY c.ID, c.NAME;
Remarque modifie la requête:
SELECT DISTINCT
, car vous voulez vraiment un GROUP BY
. IIF()
à CASE
. Je ne vois aucune raison d'utiliser une fonction conçue pour la rétrocompatibilité avec MS Access par rapport à la fonction standard SQL. Vous devez simplement utiliser la clause GROUP BY
+ MAX
aggreate au lieu de DISTINCT
SELECT contacts.ID, contacts.NAME , MAX(IIF(tags.tag = 'A', 1, 0)) as A , MAX(IIF(tags.tag = 'B', 1, 0)) as B , MAX(IIF(tags.tag = 'C', 1, 0)) as C , MAX(IIF(tags.tag = 'D', 1, 0)) as D FROM contacts LEFT JOIN TAGS ON contacts.ID = TAGS.CONTACT_ID group by contacts.ID, contacts.NAME
Comme le dit Gordon Linoff, l'utilisation du case when
SQL standard est plus compatible avec toute la database (postgres, oracle, sql server …)
IIF(tags.tag = 'A', 1, 0)
est équivalent à
CASE WHEN tags.tag = 'A' THEN 1 ELSE 0 END
SELECT contacts.ID, contacts.NAME , MAX(IIF(tags.tag = 'A', 1, 0)) as A , MAX(IIF(tags.tag = 'B', 1, 0)) as B , MAX(IIF(tags.tag = 'C', 1, 0)) as C , MAX(IIF(tags.tag = 'D', 1, 0) as D FROM contacts LEFT JOIN TAGS ON contacts.ID = TAGS.CONTACT_ID GROUP BY contacts.ID, contacts.NAME