Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql Count distinct和Null值由聚合消除_Sql_Sql Server_Sql Server 2005_Null_Aggregate - Fatal编程技术网

Sql Count distinct和Null值由聚合消除

Sql Count distinct和Null值由聚合消除,sql,sql-server,sql-server-2005,null,aggregate,Sql,Sql Server,Sql Server 2005,Null,Aggregate,我正在使用SQLServer2005。使用以下查询(从我的实际查询中简化): 有没有什么方法可以在不获取数据的情况下进行计数 “警告:聚合或其他集合操作会消除空值。” 以下是我能想到的备选方案: 关闭ANSI_警告 分为两个查询,一个使用count distinct,另一个使用where子句消除null,另一个使用sum: select t1.a, t1.countdistinctb, t2.suma from ( select a,count(distinct b) countdist

我正在使用SQLServer2005。使用以下查询(从我的实际查询中简化):

有没有什么方法可以在不获取数据的情况下进行计数

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

以下是我能想到的备选方案:

  • 关闭ANSI_警告
  • 分为两个查询,一个使用count distinct,另一个使用where子句消除null,另一个使用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 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
    
  • 忽略客户端中的警告


  • 有更好的方法吗?我可能会选择第2条路线,但不喜欢代码重复。

    如果可能返回空值,请使用

    CASE WHEN Column IS NULL THEN -1 ELSE Column END AS Column
    
    这将在查询期间将-1的所有空值分出来,它们将被计数/聚合,然后您可以在精细包装查询中执行相反的操作

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

    多亏了Eoin,我想出了一个办法。您可以对包括空值在内的值进行计数,然后删除由于空值而导致的计数(如果有)。如果您不喜欢代码重复,为什么不使用公共表表达式?e、 g

    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
    

    这是一个迟到的通知,但由于这是谷歌的回报,我想提一下

    将NULL更改为另一个值是一个坏主意(tm)

    COUNT()正在执行此操作,而不是显式执行

    相反,在子查询和返回数字的子查询中使用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(*)
    ,它不会忽略空值(因为它计算记录,而不是值)。

    我认为您以前的代码很好,数据库不应该让您感到意外,这就是它发出警告的原因,因为有些程序员可能倾向于认为DISTINCT无论如何都应该包括计算空值。我认为警告警报符合ANSI SQL标准。你的解释很有道理。尽管如此,如果可以避免警告,我还是不喜欢。我希望避免将其拆分为两个查询并合并。多亏了你的想法,我已经解决了,我会发布一个答案。我一点也不喜欢这个想法!如果数据延迟到达怎么办?或者“unknown”是一个完全有效的状态?我专门设计了一种情况,我不想在计数中包含空值。这是一个我没有想到的好主意。但我真正不喜欢的代码重复是groupby和joins,这是无法像这样消除的。谢谢。如果-1是[b]的有效数据值,并且您需要为IsNull()使用极值(例如,数据类型为MAX或MIN),这可能会导致使用此方法求和时溢出,那么另一种方法是
    count(distinct IsNull(b,-32768))-CASE WHEN SUM(CASE WHEN b为null,则1 else 0 end)=0然后0 else 1 end
    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
    
    WITH A(A) AS (SELECT NULL UNION ALL SELECT NULL UNION ALL SELECT 1)
    SELECT COUNT(*) FROM (SELECT DISTINCT A FROM A) B;