Compter les valeurs nulles et non nulles dans une colonne

10

Comment compter et récupérer null et non null sur la même colonne dans MySQL?

ma table

---------------------------------------------------
id   |    name    |      visited   |   registDate |
---------------------------------------------------
1    |    george  |       NULL     |   2014-04-01 |
---------------------------------------------------
2    |    Thomas  |       NULL     |   2014-04-15 |
---------------------------------------------------
3    |    Wilfred |        1       |   2014-04-24 |
---------------------------------------------------
4    |    paul    |        1       |   2014-04-10 |
---------------------------------------------------
5    |    elina   |       NULL     |   2014-05-03 |
---------------------------------------------------
6    |    angela  |       NULL     |   2014-04-13 |
---------------------------------------------------
7    |    elina   |        1       |   2014-05-18 |
---------------------------------------------------

Résultat attendu

month      register    visited    not visited
---------------------------------------------
05-2014       2           1          1   
---------------------------------------------
04-2014       5           2          3
---------------------------------------------
santhosh
la source

Réponses:

6

Essayer

SELECT 
   DATE_FORMAT(registDate, '%m-%Y') AS month,
   COUNT(name) AS register,
   SUM(!ISNULL(visited)) AS visited,
   SUM(ISNULL(visited)) AS not_visited
FROM mytable
GROUP BY DATE_FORMAT(registDate, '%m-%Y');

Pas besoin de créer une autre colonne.

Rodrigo Prazim
la source
2

La première chose à faire est d'ajouter une colonne pour le mois:

select *, date_format(registDate, '%Y-%m') as regist_month
from mytable

Ensuite, vous pouvez obtenir tous les chiffres:

select
  regist_month
, count(registDate) as count_registered
, sum(case when visited is not null then 1 else 0 end) as count_visited
, sum(case when visited is null then 1 else 0 end) as count_not_visited
from (
  select *, date_format(registDate, '%Y-%m') as regist_month
  from mytable
) group by regist_month
Yawar
la source
Vous pouvez utiliser le nombre au lieu de somme et de réduire l'expression un peu: count(visited). count (<column>) ne comptera que non nul. Si vous ajoutez un autre niveau d'imbrication, count_not_visited peut être déterminé comme suit:count_registered - count_visited
Lennart
1

Par exemple, pour compter toutes les valeurs non nulles d'une colonne col1, vous pouvez simplement utiliser count(col1) as cnt_col1. Mais, pour être plus évident, vous pouvez utiliser la sum()fonction et l' IS NOT NULLopérateur, devenant sum(col1 IS NOT NULL). C'est parce que l' IS NOT NULLopérateur retourne un int: 1 pour vrai et 0 pour faux.

Afin de compter les valeurs nulles, vous pouvez utiliser l' IS NULLopérateur, qui renvoie 1 lorsque la valeur est nulle. Comme avant, avec l' sum()opérateur.

Étant donné que, pour obtenir les inscrits, visités et non visités pour chaque mois, voici ce que vous pouvez faire:

SELECT
date_format(registDate, '%m-%Y') as month,
count(registDate) as register,
sum(visited is not null) as visited,
sum(visited is null) as 'not visited'
GROUP BY
date_format(registDate, '%m-%Y')

Notez que vous pouvez afficher la colonne 'non visité' avec l'espace, simplement en citant, en double ou en utilisant des astuces (`).

Une autre approche pour sélectionner et regrouper par mois serait de concaténer le mois avec l'année, comme ceci concat(month(registDate), '-', date(registDate)). Mais c'est moins élégant.

L' caseopérateur proposé dans d'autres réponses est parfaitement valable, mais je pense qu'il est plus adéquat pour d'autres situations. Et c'est plus verbeux.

Nuno Pereira
la source