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:

  1. Volviendo ANSI_WARNINGS off
  2. 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
    
  3. 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.

¿Fue útil?

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
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top