Sql Server相当于COUNTIF聚合函数

sen*_*nfo 152 sql sql-server-2005

我正在构建一个带有GROUP BY子句的查询,该子句需要能够仅根据某个条件计算记录(例如,只计算某个列值等于1的记录).

SELECT  UID, 
        COUNT(UID) AS TotalRecords, 
        SUM(ContractDollars) AS ContractDollars,
        (COUNTIF(MyColumn, 1) / COUNT(UID) * 100) -- Get the average of all records that are 1
FROM    dbo.AD_CurrentView
GROUP BY UID
HAVING  SUM(ContractDollars) >= 500000
Run Code Online (Sandbox Code Playgroud)

COUNTIF()行明显失败,因为没有调用本机SQL函数COUNTIF,但这里的想法是确定MyColumn值为"1"的所有行的百分比.

有关如何在MS SQL 2005环境中正确实现它的任何想法?

Jos*_*rke 315

您可以使用SUM(而不是COUNT!)结合CASE语句,如下所示:

SELECT SUM(CASE WHEN myColumn=1 THEN 1 ELSE 0 END)
FROM AD_CurrentView
Run Code Online (Sandbox Code Playgroud)

注意:在我自己的测试中,NULLs不是问题,尽管这可能与环境有关.您可以处理空值,例如:

SELECT SUM(CASE WHEN ISNULL(myColumn,0)=1 THEN 1 ELSE 0 END)
FROM AD_CurrentView
Run Code Online (Sandbox Code Playgroud)

  • (我知道OP询问了MS SQL,但只是对SQLite用户做同样事情的一个小评论)SQLite没有`ISNULL`,而是你可以做`CASE WHEN myColumn IS NULL`,或者使用`ifnull`(https: //stackoverflow.com/a/799406/1861346) (2认同)
  • 你能解释一下为什么是“sum”而不是“count”吗? (2认同)

Chr*_*fer 50

我经常按照乔希推荐的那样做,但是头脑风暴并测试了一种我感觉分享的轻微选择.

您可以利用COUNT(ColumnName)不计算NULL的事实,并使用以下内容:

SELECT COUNT(NULLIF(0, myColumn))
FROM AD_CurrentView
Run Code Online (Sandbox Code Playgroud)

NULLIF - 如果两个传入的值相同,则返回NULL.

优点:表达您对COUNT行的意图,而不是使用SUM()表示法.缺点:不清楚它是如何工作的("魔术"通常是坏的).

  • 当一个组只包含空值时,该解决方案可以给出与总和不同的答案,它导致1而不是0. (2认同)

asg*_*eo1 19

我会使用这种语法.它与Josh和Chris的建议相同,但它的优点是ANSI兼容并且不依赖于特定的数据库供应商.

select count(case when myColumn = 1 then 1 else null end)
from   AD_CurrentView
Run Code Online (Sandbox Code Playgroud)

  • Chris的答案是Stndard SQL兼容(提示:`NULLIF`包含在标准SQL-92中).通过将`isnull`替换为`COALESCE`,可以轻松地将Josh的答案转换为标准SQL. (2认同)

maf*_*oft 5

怎么样

SELECT id, COUNT(IF status=42 THEN 1 ENDIF) AS cnt
FROM table
GROUP BY table
Run Code Online (Sandbox Code Playgroud)

比。。。短CASE:)

之所以有效,是因为COUNT()不计算 null 值,并且IF/CASE在不满足条件且不存在 时返回 null ELSE

我认为这比使用SUM().