1
votes

Comment compter des données SQL mais aussi avoir un champ qui peut être présent ou non?

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.


0 commentaires

3 Réponses :


2
votes

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 >


0 commentaires

0
votes
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; 

0 commentaires

1
votes

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?


0 commentaires