Sql Server相当于一个COUNTIF聚合函数

我正在用一个GROUP BY子句构build一个查询,这个查询只需要根据一定的条件对logging进行计数(例如只计算特定列值等于1的logging)。

 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 

COUNTIF()行明显失败,因为没有本地的SQL函数叫做COUNTIF ,但是这里的想法是确定MyColumn具有值'1'的所有行的百分比。

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

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

 SELECT SUM(CASE WHEN myColumn=1 THEN 1 ELSE 0 END) FROM AD_CurrentView 

注意:在我自己的testing中, NULL不是一个问题,尽pipe这可能是依赖于环境的。 你可以处理空值,例如:

 SELECT SUM(CASE WHEN ISNULL(myColumn,0)=1 THEN 1 ELSE 0 END) FROM AD_CurrentView 

我通常做乔希推荐的东西,但是头脑风暴,testing了一个我觉得喜欢分享的稍微有点狡猾的select。

您可以利用COUNT(ColumnName)不计数NULL的事实,并使用如下所示:

 SELECT COUNT(NULLIF(0, myColumn)) FROM AD_CurrentView 

NULLIF – 如果传入的值相同,则返回NULL。

优点:expression您对COUNT行的意图,而不是使用SUM()表示法。 缺点:不清楚它是如何工作的(“魔法”通常是不好的)。

我会用这个语法。 它实现了Josh和Chris的build议,但是具有ANSI的优势,并且不受特定数据库供应商的约束。

 select count(case when myColumn = 1 then 1 else null end) from AD_CurrentView 

加上乔希的回答,

 SELECT COUNT(CASE WHEN myColumn=1 THEN AD_CurrentView.PrimaryKeyColumn ELSE NULL END) FROM AD_CurrentView 

在SQL Server 2012中工作得很好(在SQL Server 2012中),没有将“count”改为“sum”,同样的逻辑可移植到其他“条件聚合”。 例如,基于条件的总结:

 SELECT SUM(CASE WHEN myColumn=1 THEN AD_CurrentView.NumberColumn ELSE 0 END) FROM AD_CurrentView 

不是产品特定的,但是SQL标准提供

SELECT COUNT() FILTER WHERE <condition-1>, COUNT() FILTER WHERE <condition-2>, ... FROM ...

以此目的。 或者类似的东西,我不知道我的帽子顶部。

当然,供应商更愿意坚持自己的专有解决scheme。

为什么不喜欢这个?

 SELECT count(1) FROM AD_CurrentView WHERE myColumn=1 

怎么样

 SELECT id, COUNT(IF status=42 THEN 1 ENDIF) AS cnt FROM table GROUP BY table 

CASE更短:)

因为COUNT()不计算空值,因此当条件未满足且没有ELSEIF / CASE返回null。

我认为这比使用SUM()更好。