Recuento diferente y el valor Null se elimina por un agregado
-
21-08-2019 - |
Pregunta
Estoy usando SQL Server 2005. Con la consulta a continuación (simplificado de mi consulta real):
select a,count(distinct b),sum(a) from
(select 1 a,1 b union all
select 2,2 union all
select 2,null union all
select 3,3 union all
select 3,null union all
select 3,null) a
group by a
¿Hay alguna manera de hacer un recuento diferente sin conseguir
"Advertencia:. Valor nulo es eliminado por una operación SET agregado o"
Estas son las alternativas que se me ocurren:
- Volviendo ANSI_WARNINGS off
-
La separación en dos consultas, una con recuento diferente y una cláusula where para eliminar valores nulos, uno con la suma:
select t1.a, t1.countdistinctb, t2.suma from ( select a,count(distinct b) countdistinctb from ( select 1 a,1 b union all select 2,2 union all select 2,null union all select 3,3 union all select 3,null union all select 3,null ) a where a.b is not null group by a ) t1 left join ( select a,sum(a) suma from ( select 1 a,1 b union all select 2,2 union all select 2,null union all select 3,3 union all select 3,null union all select 3,null ) a group by a ) t2 on t1.a=t2.a
-
No haga caso de la advertencia en el cliente
¿Hay una mejor manera de hacer esto? Probablemente voy a bajar la ruta 2, pero no me gusta la duplicación de código.
Solución
select a,count(distinct isnull(b,-1))-sum(distinct case when b is null then 1 else 0 end),sum(a) from
(select 1 a,1 b union all
select 2,2 union all
select 2,null union all
select 3,3 union all
select 3,null union all
select 3,null) a
group by a
Gracias a Eoin trabajé encontrar una manera de hacer esto. Usted puede contar con distintos valores incluidos los nulos y luego retire el recuento debido a los nulos si había algún usando una suma distinta.?
Otros consejos
En cualquier lugar que haya regresado posiblemente un nulo, utilice
CASE WHEN Column IS NULL THEN -1 ELSE Column END AS Column
Esa voluntad sub a cabo todos sus valores nulos de -1 para la duración de la consulta y serán contados / agregarse como tal, a continuación, puedes hacer lo contrario en su consulta de envolver bien ...
SELECT
CASE WHEN t1.a = -1 THEN NULL ELSE t1.a END as a
, t1.countdistinctb
, t2.suma
Esta es una nota de retraso, pero siendo que fue el retorno de Google, que quería mencionar a él.
Cambio de NULL a otro valor es una mala idea (tm).
COUNT () lo está haciendo, no DISTINCT.
lugar, utilice DISTINCT en una subconsulta y que devuelve un número, y agregado que en la consulta externa.
Un ejemplo sencillo de esto es:
WITH A(A) AS (SELECT NULL UNION ALL SELECT NULL UNION ALL SELECT 1)
SELECT COUNT(*) FROM (SELECT DISTINCT A FROM A) B;
Esto permite COUNT(*)
para ser utilizado, que no ignora NULL (porque cuenta registros, no los valores).
Si no le gusta la duplicación de código a continuación, por qué no utilizar una expresión de tabla común? p.ej.
WITH x(a, b) AS
(
select 1 a,1 b union all
select 2,2 union all
select 2,null union all
select 3,3 union all
select 3,null union all
select 3,null
)
select t1.a, t1.countdistinctb, t2.suma from
(
select a,count(distinct b) countdistinctb from
x a
where a.b is not null
group by a
) t1
left join
(
select a,sum(a) suma from
x a
group by a
) t2 on t1.a=t2.a