J'essaie de trouver la bonne requête SQL pour regrouper les données, mais j'inclus également un booléen (OUI / NON) si au moins une des lignes groupées a une certaine valeur.
Voici un exemple concret pour aider à visualiser:
Disons que j'ai des données comme celle-ci, peut-être dans une table appelée "expériences" avec des champs comme celui-ci:
user_id count(*) did_complete? 23 3 TRUE 17 1 FALSE
Et disons que j'ai ces données:
user_id count(*) completed_at 23 2 NULL 23 1 2019-09-19 17 1 NULL
Je veux écrire une requête SQL qui fait un group_by the user_id afin que je puisse avoir un compte, mais inclut également des booléens valeur indiquant si au moins une de leurs lignes incluait une valeur completed_at.
Ainsi, je ne peux pas simplement faire:
SELECT user_id, count(*), completed_at from db group by user_id, completed_at;
Cela se termine comme:
1, "test experiment", 23, 2019-09-10, NULL 2, "test experiment", 17, 2019-09-15, NULL 3, "test experiment", 23, 2019-09-18, 2019-09-19 4, "test experiment", 23, 2019-09-19, NULL
Ce que j'aimerais, c'est une requête qui me permette de finir avec quelque chose comme:
id, experiment_name, user_id, created_at, completed_at
Mais je ' Je suis perplexe sur cette partie. J'ai essayé de chercher SO ici, mais je n'arrive pas à comprendre comment formuler cela comme une question courte et interrogeable.
3 Réponses :
Vous utilisez une fonction d'agrégation avec une expression conditionnelle pour vérifier si au moins un enregistrement dans le groupe a une valeur completed_at
non nulle:
SELECT user_id, COUNT(*) cnt, MAX(CASE WHEN completed_at IS NOT NULL THEN 1 ELSE 0 END) did_complete FROM experiments GROUP BY user_id
Je habituellement préférez utiliser 0
/ 1
plutôt que TRUE / FALSE
car les nombres sont beaucoup plus portables entre différents SGBDR que les booléens.
p >
SELECT MAX(CASE WHEN completed_at IS NOT NULL THEN 1 ELSE 0 END) AS HasCompleted, count(*) AS CNT, MAX(completed_at) LastCompleted from db group by user_id;
Vous devez sélectionner la colonne Nullable comme oui / non et que grouper par ce champ Quelque chose comme
SELECT user_id, count(*), switch if is null completed_at then 0 else 1 end as nullableField from db group by user_id, nullableField;
Regardez également cette question Comment renvoyer mes enregistrements groupés par NULL et NOT NULL?