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()
不计算空值,因此当条件未满足且没有ELSE
时IF
/ CASE
返回null。
我认为这比使用SUM()
更好。