Contare i valori null e non null in una colonna


10

Come contare e recuperare null e non null sulla stessa colonna in MySQL?

MyTable

---------------------------------------------------
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 |
---------------------------------------------------

Risultato atteso

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

Risposte:


6

Provare

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');

Non è necessario creare un'altra colonna.


2

La prima cosa da fare è "aggiungere" una colonna per il mese:

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

Quindi puoi ottenere tutti i conteggi:

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

È possibile utilizzare conta invece di somma e abbreviare l'espressione un po ': count(visited). count (<column>) conterà solo non null. Se si aggiunge un altro livello di annidamento, count_not_visited può essere determinato come:count_registered - count_visited
Lennart,

1

Per contare tutti i valori non nulli per una colonna, diciamo col1, puoi semplicemente usare count(col1) as cnt_col1. Ma, per essere più ovvi, puoi usare la sum()funzione e l' IS NOT NULLoperatore, diventando sum(col1 IS NOT NULL). Questo perché l' IS NOT NULLoperatore restituisce un int: 1 per true e 0 per false.

Per contare i valori null è possibile utilizzare l' IS NULLoperatore, che restituisce 1 quando il valore è null. Come prima, con l' sum()operatore.

Dato che, al fine di ottenere la registrazione, visitata e non visitata per ogni mese, questo è ciò che puoi fare:

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')

Si noti che è possibile generare la colonna "non visitato" con lo spazio, semplicemente citando, virgolette doppie o usando i backtick (`).

Un altro approccio per selezionare e raggruppare per mese sarebbe concatenare il mese con l'anno, come questo concat(month(registDate), '-', date(registDate)). Ma è meno elegante.

L' caseoperatore proposto in altre risposte è perfettamente valido, ma lo ritengo più adeguato per altre situazioni. Ed è più prolisso.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.