Conteggio e un valore Null viene eliminato da un aggregato
-
21-08-2019 - |
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:
- Attivazione ANSI_WARNINGS off
-
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
-
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.
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