web-dev-qa-db-fra.com

Comptage des valeurs nulles et non nulles dans une requête unique

J'ai une table 

create table us
(
 a number
);

Maintenant, j'ai des données comme:

a
1
2
3
4
null
null
null
8
9

Maintenant, j'ai besoin d'une seule requête pour compter les valeurs null et not null dans la colonne a 

105
prabin

Cela fonctionne pour Oracle et SQL Server (vous pourrez peut-être le faire fonctionner sur un autre SGBDR):

select sum(case when a is null then 1 else 0 end) count_nulls
     , count(a) count_not_nulls 
  from us;

Ou:

select count(*) - count(a), count(a) from us;
190
user155789

Si j'ai bien compris, vous voulez compter tous les NULL et tous les NOT NULL dans une colonne ...

Si c'est correct:

SELECT count(*) FROM us WHERE a IS NULL 
UNION ALL
SELECT count(*) FROM us WHERE a IS NOT NULL

Edité pour avoir la requête complète, après avoir lu les commentaires:]


SELECT COUNT(*), 'null_tally' AS narrative 
  FROM us 
 WHERE a IS NULL 
UNION
SELECT COUNT(*), 'not_null_tally' AS narrative 
  FROM us 
 WHERE a IS NOT NULL;
50
Alberto Zaccagni

Voici une version rapide et sale qui fonctionne sur Oracle:

select sum(case a when null then 1 else 0) "Null values",
       sum(case a when null then 0 else 1) "Non-null values"
from us
36
christopheml

Si j'ai bien compris votre requête, vous venez d’exécuter ce script et d’obtenir les lignes Total Null, Total NotNull,

select count(*) - count(a) as 'Null', count(a) as 'Not Null' from us;
16
Ariful Haque

généralement j'utilise cette astuce

select sum(case when a is null then 0 else 1 end) as count_notnull,
       sum(case when a is null then 1 else 0 end) as count_null
from tab
group by a
12
elle0087

pour les non nuls

select count(a)
from us

pour les nuls

select count(*)
from us

minus 

select count(a)
from us

Par conséquent

SELECT COUNT(A) NOT_NULLS
FROM US

UNION

SELECT COUNT(*) - COUNT(A) NULLS
FROM US

devrait faire le travail

5
EvilTeach

C'est un peu délicat. Supposons que la table ne comporte qu'une colonne, les valeurs Count (1) et Count (*) donneront des valeurs différentes.

set nocount on
    declare @table1 table (empid int)
    insert @table1 values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(NULL),(11),(12),(NULL),(13),(14);

    select * from @table1
    select COUNT(1) as "COUNT(1)" from @table1
    select COUNT(empid) "Count(empid)" from @table1

Résultats de la requête

Comme vous pouvez le voir dans l'image, le premier résultat montre que la table a 16 lignes. dont deux lignes sont NULL. Ainsi, lorsque nous utilisons Count (*), le moteur de requête compte le nombre de lignes. Le résultat de compte est donc égal à 16. Mais dans le cas de Count (empid), il compte les valeurs non NULL dans la colonne empid. Nous avons donc obtenu le résultat en tant que 14. 

ainsi, chaque fois que nous utilisons COUNT (Column), assurez-vous de prendre en compte les valeurs NULL, comme indiqué ci-dessous.

select COUNT(isnull(empid,1)) from @table1

comptera les valeurs NULL et Non NULL.

Note: La même chose s'applique même lorsque la table est composée de plusieurs colonnes. Nombre (1) donnera le nombre total de lignes indépendamment des valeurs NULL/Non-NULL. Ce n'est que lorsque les valeurs de colonne sont comptées à l'aide de Count (Column) que nous devons nous occuper des valeurs NULL.

4
Santhoshkumar LM

Juste pour fournir une autre alternative, Postgres 9.4+ permet d’appliquer un FILTER aux agrégats :

SELECT
  COUNT(*) FILTER (WHERE a IS NULL) count_nulls,
  COUNT(*) FILTER (WHERE a IS NOT NULL) count_not_nulls
FROM us;

SQLFiddle: http://sqlfiddle.com/#!17/80a24/5

3
Abe Voelker

J'ai eu un problème similaire: compter toutes les valeurs distinctes, en comptant les valeurs nulles comme 1. Un compte simple ne fonctionne pas dans ce cas, car il ne prend pas en compte les valeurs nulles.

Voici un extrait qui fonctionne avec SQL et n’implique pas la sélection de nouvelles valeurs . cette colonne:

SELECT COUNT(n)
FROM (
    SELECT *, row_number() OVER (ORDER BY [MyColumn] ASC) n
    FROM (
        SELECT DISTINCT [MyColumn]
                    FROM [MyTable]
        ) items  
) distinctItems
2
Starnuto di topo

utilisez la fonction intégrée ISNULL.


1
Serget

Si vous utilisez MS SQL Server ... 

SELECT COUNT(0) AS 'Null_ColumnA_Records',
(
    SELECT COUNT(0)
    FROM your_table
    WHERE ColumnA IS NOT NULL
) AS 'NOT_Null_ColumnA_Records'
FROM your_table
WHERE ColumnA IS NULL;

Je ne vous recommande pas de faire ceci ... mais ici vous l'avez

1
Andrei

Voici deux solutions:

Select count(columnname) as countofNotNulls, count(isnull(columnname,1))-count(columnname) AS Countofnulls from table name

OR

Select count(columnname) as countofNotNulls, count(*)-count(columnname) AS Countofnulls from table name
1
Amal Hari

J'ai créé la table dans postgres 10 et les deux éléments suivants ont fonctionné:

select count(*) from us

et

select count(a is null) from us

1
skrillybrick

Essayer

SELECT 
   SUM(ISNULL(a)) AS all_null,
   SUM(!ISNULL(a)) AS all_not_null
FROM us;

Simple!

1
Rodrigo Prazim

Juste au cas où vous le voudriez dans un seul enregistrement:

select 
  (select count(*) from tbl where colName is null) Nulls,
  (select count(*) from tbl where colName is not null) NonNulls 

;-)

0
Sparhawk_

si c'est mysql, vous pouvez essayer quelque chose comme ceci.

select 
   (select count(*) from TABLENAME WHERE a = 'null') as total_null, 
   (select count(*) from TABLENAME WHERE a != 'null') as total_not_null
FROM TABLENAME
0
TigerTiger

Essaye ça..

SELECT CASE 
         WHEN a IS NULL THEN 'Null' 
         ELSE 'Not Null' 
       END a, 
       Count(1) 
FROM   us 
GROUP  BY CASE 
            WHEN a IS NULL THEN 'Null' 
            ELSE 'Not Null' 
          END 
0
Ayush Raj
SELECT
    ALL_VALUES
    ,COUNT(ALL_VALUES)
FROM(
        SELECT 
        NVL2(A,'NOT NULL','NULL') AS ALL_VALUES 
        ,NVL(A,0)
        FROM US
)
GROUP BY ALL_VALUES
0
pantha istiaque
select count(isnull(NullableColumn,-1))
0
Imran Shamszadeh
SELECT SUM(NULLs) AS 'NULLS', SUM(NOTNULLs) AS 'NOTNULLs' FROM 
    (select count(*) AS 'NULLs', 0 as 'NOTNULLs' FROM us WHERE a is null
    UNION select 0 as 'NULLs', count(*) AS 'NOTNULLs' FROM us WHERE a is not null) AS x

C'est fugly, mais il retournera un seul enregistrement avec 2 colonnes indiquant le nombre de valeurs NULL vs non NULL.

0
C-Pound Guru

Toutes les réponses sont soit fausses, soit extrêmement obsolètes.

La manière simple et correcte de faire cette requête utilise la fonction COUNT_IF.

SELECT
  COUNT_IF(a IS NULL) AS nulls,
  COUNT_IF(a IS NOT NULL) AS not_nulls
FROM
  us
0
Martín Fixman

pour compter les valeurs non nulles

select count(*) from us where a is not null;

pour compter les valeurs nulles

 select count(*) from us where a is null;
0
Deep Shah

En partant d'Alberto, j'ai ajouté le rollup.

 SELECT [Narrative] = CASE 
 WHEN [Narrative] IS NULL THEN 'count_total' ELSE    [Narrative] END
,[Count]=SUM([Count]) FROM (SELECT COUNT(*) [Count], 'count_nulls' AS [Narrative]  
FROM [CrmDW].[CRM].[User]  
WHERE [EmployeeID] IS NULL 
UNION
SELECT COUNT(*), 'count_not_nulls ' AS narrative 
FROM [CrmDW].[CRM].[User] 
WHERE [EmployeeID] IS NOT NULL) S 
GROUP BY [Narrative] WITH CUBE;
0
Brian Connelly

Cela fonctionne dans T-SQL. Si vous ne comptez que le nombre d'objets et que vous souhaitez inclure les valeurs NULL, utilisez COALESCE au lieu de la casse.

IF OBJECT_ID('tempdb..#us') IS NOT NULL
    DROP TABLE #us

CREATE TABLE #us
    (
    a INT NULL
    );

INSERT INTO #us VALUES (1),(2),(3),(4),(NULL),(NULL),(NULL),(8),(9)

SELECT * FROM #us

SELECT CASE WHEN a IS NULL THEN 'NULL' ELSE 'NON-NULL' END AS 'NULL?',
        COUNT(CASE WHEN a IS NULL THEN 'NULL' ELSE 'NON-NULL' END) AS 'Count'
    FROM #us
    GROUP BY CASE WHEN a IS NULL THEN 'NULL' ELSE 'NON-NULL' END

SELECT COALESCE(CAST(a AS NVARCHAR),'NULL') AS a,
        COUNT(COALESCE(CAST(a AS NVARCHAR),'NULL')) AS 'Count'
    FROM #us
    GROUP BY COALESCE(CAST(a AS NVARCHAR),'NULL')
0
DaveX