2009-08-13 27 views
76

Tengo una tablaContando los valores nulos y no nulos en una sola consulta

create table us 
(
a number 
); 

Ahora tengo datos como:

a 
1 
2 
3 
4 
null 
null 
null 
8 
9 

Ahora necesito una sola consulta para contar nula y no valores nulos en la columna a

+2

Hola, ¿dónde necesita este tipo de código de base de datos de conteo en qué base de datos de idiomas somos t alking Saludos cordiales, Iordan – IordanTanev

+1

Me sorprende que ninguna respuesta contenga una simple unión de select count (*) ... –

+0

@Lieven: ¿Por qué diablos usarías una 'unión' aquí? La respuesta de Montecristo es, de lejos, la mejor solución. – Eric

Respuesta

-3

Número de elementos donde a es nulo:

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

Número de elementos en los que a no es nulo:

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

La pregunta es para una sola consulta. – DreamWave

4

para los no nulos

select count(a) 
from us 

para nulos

select count(*) 
from us 

minus 

select count(a) 
from us 

Por lo tanto

SELECT COUNT(A) NOT_NULLS 
FROM US 

UNION 

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

debe hacer el trabajo

+3

Buena salsa, hombre, mira los planes de ejecución para estas consultas. Está iniciando escaneos de tabla a la izquierda y a la derecha, especialmente donde hay una declaración tan sangrienta y simple ('select count (*) from t donde a es nulo') que hace esto. – Eric

+1

No tengo una base de datos útil para mirar, pero la columna está indexada o no. Si es así, sucede a través de un escaneo de rango, de lo contrario, se queda con un escaneo de tabla completo. En Oracle, los NULL no están almacenados en el índice, así que sospecho que tu ejemplo no es mucho mejor. Tu milage puede muy. – EvilTeach

+0

@EvilTeach: los índices solo son útiles cuando no está retrocediendo> ~ 10% de las filas. Después de eso, se inician los escaneos completos. En este caso, obtendrá el escaneo al menos una vez, sino dos veces. – Eric

0

si su MySQL, puede intentar algo como esto.

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

¿Has probado eso? –

31

Aquí es una versión rápida y sucia que funciona en 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 
+1

La sintaxis similar también funcionaría en SQL Server. Además, hacerlo de esta manera solo escaneará la tabla una vez; las soluciones de UNION harán dos escaneos de tabla. Irrelevante para mesas pequeñas, muy importante para las grandes. –

+1

El único cambio para SQL Server es '" Valores nulos "' tendría que convertirse en ''Valores nulos''. Comillas simples, no dobles. – Eric

+0

SQLServer usa un * index scan * para esta consulta frente a dos * index seek * usando una unión. En una mesa con 40,000 filas, no hay diferencia de velocidad. –

42

Si he entendido bien que desea contar todo NULL y no todo NULL en una columna ...

Si eso es correcto:

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

editarse para la consulta completa, después de leer los comentarios:]


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; 
+6

+1: Por mucho, la manera más simple y rápida. Me sorprendió cuando cada respuesta no era esta. – Eric

+5

Sí, pero no. Creo que quiere tener el número de NULL y no NULL en una sola consulta ... Estás diciendo cómo hacerlo en dos consultas ... – romaintaz

+0

@romaintaz: Muy bien. Leí el título como la pregunta. En cinco ediciones, nadie pensó en arreglarlo. Yeesh. – Eric

156

Esto funciona para Oracle y SQL Server (que podría ser capaz de conseguir que funcione en otro RDBMS):

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

O:

select count(*) - count(a), count(a) from us; 
+9

creas o no, eso es ANSI SQL ... – Eric

+0

muy fresco. Estoy sospechando un pase también. – EvilTeach

+0

Usando la distinción entre 'count (*)' y 'count (a)' también funciona bien con 'grupo BY' – shannon

1

Si está utilizando 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; 

Yo no recomiendo que hagas esto ... pero aquí lo tienes (en la misma mesa como resultado)

0
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 

Es fugly, pero va a devolver un solo registro con 2 cols indicando el número de nulos vs no nulos.

1

usan la función integrada ISNULL.


+0

Esta es también una respuesta digna. Yo he encontrado que COUNT (DISTINCT ISNULL (A '')) funciona incluso mejor que COUNT (DISTINCT A) + SUM (CASE cuando A es nulo, 1 ELSE 0 END) – Vladislav

-1

En caso de que lo querían en un solo registro:

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

;-)

1

Aquí hay dos soluciones:

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

O

Select count(columnname) as countofNotNulls, count(*)-count(columnname) AS Countofnulls from table name 
0

select count (isnull (NullableColumn, -1))

2

Tuve un problema similar: contar todos los valores distintos, contando los valores nulos como 1, también. Un simple recuento no funciona en este caso, ya que no toma en cuenta los valores nulos.

He aquí un fragmento que funciona en SQL y que no implique la selección de nuevos valores. Básicamente, una vez llevado a cabo el, también devolverá el número distinta fila en una nueva columna (n) utilizando la función row_number(), a continuación, realizar un recuento en esa columna:

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

Trate

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

¡Sencillo!

-1

para contar no valores nulos

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

para el recuento de valores nulos

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

El op pedido sola consulta :) – infografnet

0

Esto funciona de T-SQL. Si acaba de contar el número de algo y que desea incluir los nulos, usar COALESCE en lugar de caso.

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

Edificio de Alberto, he añadido el paquete.

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

que he entendido la consulta, Usted acaba de ejecutar este script y obtener total nulo, filas totales notnull,

select count(*) - count(a) as 'Null', count(a) as 'Not Null' from us; 
3

Esto es poco complicado. Supongamos que la tabla tiene sólo una columna, entonces el Conde (1) y el conde (*) dará a valores diferentes.

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 

Query Results

Como se puede ver en la imagen, el primer resultado muestra la tabla tiene 16 filas. de las cuales dos filas son NULL. Así que cuando usamos Count (*) el motor de consulta cuenta el número de filas, así que nos dieron como resultado del recuento 16. Sin embargo, en caso de Count (empid) contaba los valores no nulos en la columna empid . Así que obtuvimos el resultado como 14.

así que cada vez que usemos COUNT (Columna) asegúrese de que nos ocupamos de los valores NULL como se muestra a continuación.

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

contarán los valores NULL y Non-NULL.

Nota: Lo mismo se aplica incluso cuando la mesa está compuesta por más de una columna. El recuento (1) dará el número total de filas, independientemente de los valores NULL/Non-NULL. Solo cuando los valores de la columna se cuentan usando Count (Column) necesitamos cuidar los valores NULL.

7

por lo general yo uso este truco

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