Domanda

sto usando SQL Server 2005. Con la domanda sotto (semplificato dal mio vero query):

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

C'è un modo per fare un conteggio distinto senza ottenere

"Warning:. Valore Null viene eliminato da un aggregato o altra operazione SET"

Ecco le alternative mi vengono in mente:

  1. Attivazione ANSI_WARNINGS off
  2. La separazione in due query, una con conteggio distinto e una clausola WHERE per eliminare i null, uno con la somma:

    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. Ignorare l'avviso nel client

C'è un modo migliore per fare questo? Io probabilmente scendo percorso 2, ma non mi piace la duplicazione del codice.

È stato utile?

Soluzione

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

Grazie a Eoin ho ideato un modo per fare questo. Potete contare distinti i valori inclusi i valori nulli e quindi rimuovere il conteggio a causa di valori nulli se c'erano utilizzando una somma distinta.

Altri suggerimenti

ovunque ci sia un null possibilmente restituito, utilizzare

CASE WHEN Column IS NULL THEN -1 ELSE Column END AS Column

Questa volontà sub tutti i valori Null per -1 per tutta la durata della query e saranno contati / aggregati, come tale, allora si può solo fare il contrario nella query involucro bene ...

SELECT  
    CASE WHEN t1.a = -1 THEN NULL ELSE t1.a END as a
    , t1.countdistinctb
    , t2.suma

Questa è una nota in ritardo, ma essendo era il ritorno su Google, ho voluto parlarne.

La modifica NULL ad un altro valore è una cattiva idea (tm).

COUNT () sta facendo, non DISTINCT.

Invece, utilizzare DISTINCT in una sottoquery e che restituisce un numero e aggregare che nella query esterna.

Un semplice esempio di questo è:

WITH A(A) AS (SELECT NULL UNION ALL SELECT NULL UNION ALL SELECT 1)
SELECT COUNT(*) FROM (SELECT DISTINCT A FROM A) B;

Questo permette di COUNT(*) da utilizzare, che non ignora i NULL (perché conta i record, non valori).

Se non ti piace il codice di duplicazione allora perché non utilizzare un'espressione di tabella comune? per esempio.

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
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top