簡體   English   中英

計算distinct和Null值由聚合消除

[英]Count distinct and Null value is eliminated by an aggregate

我正在使用SQL Server 2005.使用下面的查詢(從我的真實查詢簡化):

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

有沒有辦法在沒有得到的情況下進行計數

“警告:聚合或其他SET操作消除了空值。”

以下是我能想到的替代方案:

  1. 關閉ANSI_WARNINGS
  2. 分成兩個查詢,一個是count distinct,一個是where子句來消除空值,一個是sum:

     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 ab 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. 忽略客戶端中的警告

有一個更好的方法嗎? 我可能會沿着路線2前進,但不喜歡代碼重復。

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

感謝Eoin,我找到了一種方法來做到這一點。 您可以計算不同的值,包括空值,然后刪除由於空值計數,如果有任何使用不同的和。

這是一個遲到的說明,但正是谷歌的回歸,我想提及它。

將NULL更改為另一個值是一個壞主意(tm)。

COUNT()正在這樣做,而不是DISTINCT。

相反,在子查詢中使用DISTINCT並返回一個數字,並在外部查詢中聚合。

一個簡單的例子是:

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

這允許使用COUNT(*) ,它不會忽略NULL(因為它計算記錄,而不是值)。

在任何可能返回null的地方,請使用

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

這將在查詢期間將所有Null值分配為-1,並且它們將被計算/聚合,然后您可以在精細包裝查詢中執行相反操作...

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

如果您不喜歡代碼重復,那么為什么不使用公用表表達式? 例如

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM