我有一个数据库,有很多列通过,失败,空白指标我想创建一个函数来计算每种类型的值,并从计数中创建一个表。我想的结构是这样的| Value | x | y | z ||-------|------------------|-------------------|---|---|---|---|---|---|---|| pass | count if x=pass | count if y=pass | count if z=pass | | | | | | || fail |如果x=失败则计数|如果y=失败则计数|如果z=失败则计数| | | | | | || blank | count if x=blank | count if y=blank | count if z=blank | | | | | | || total | count(x) | count(y) | count(z) | | | | | | |
其中x,y,z是来自另一个表的列。
我不知道哪一个是最好的方法提前感谢大家
我尝试了这个结构,但它显示语法错误
CREATE FUNCTION Countif (columnx nvarchar(20),value_compare nvarchar(10))
RETURNS Count_column_x AS
BEGIN
IF columnx=value_compare
count(columnx)
END
RETURN
END
另外,我不知道如何将每个计数添加到我试图创建的实际表
条件计数(或任何条件聚合)通常可以内联完成,通过在聚合函数中放置一个CASE
表达式,该表达式有条件地返回要聚合的值或要跳过的NULL。
一个例子是COUNT(CASE WHEN SelectMe = 1 THEN 1 END)
。这里的聚合值是1
(它可以是COUNT()
的任何非空值)。(对于其他聚合函数,将提供一个更有意义的值。)隐式的ELSE
返回一个不被计算的NULL
。
对于您的问题,我认为首先要做的是UNPIVOT
您的数据,将列名和值并排放置。然后,可以按值分组,并使用如上所述的条件聚合来计算结果。在添加了(1)使用WITH ROLLUP
的总计行,(2)CASE
语句来调整空白行和总计行的标签,以及(3)一些ORDER BY
技巧来获得正确的结果之后,我们完成了。
结果可能类似于:
SELECT
CASE
WHEN GROUPING(U.Value) = 1 THEN 'Total'
WHEN U.Value = '' THEN 'Blank'
ELSE U.Value
END AS Value,
COUNT(CASE WHEN U.Col = 'x' THEN 1 END) AS x,
COUNT(CASE WHEN U.Col = 'y' THEN 1 END) AS y
FROM @Data D
UNPIVOT (
Value
FOR Col IN (x, y)
) AS U
GROUP BY U.Value WITH ROLLUP
ORDER BY
GROUPING(U.Value),
CASE U.Value WHEN 'Pass' THEN 1 WHEN 'Fail' THEN 2 WHEN '' THEN 3 ELSE 4 END,
U.VALUE
样本数据:
我认为你不需要一个通用的解决方案,如一个函数值作为参数。
也许,你可以创建一个视图分组你的数据,然后调用这个视图过滤你的值。
你的视图主体应该是这样的
select value, count(*) as Total
from table_name
group by value
请把你的情况解释清楚,这样我才能帮助你。
您可以通过按状态列分组来实现。
select status, count(*) as total
from some_table
group by status
与其创建一个全新的表,不如考虑使用视图。这是一个看起来像表的查询。
create view status_counts as
select status, count(*) as total
from some_table
group by status
你可以选择select total from status_counts where status = 'pass'
或类似的,它将运行查询。
您也可以创建一个"物化视图"。这类似于视图,但是结果被写入到一个真实的表中。SQL Server的特殊之处在于它会为你保持这个表的更新。
create materialized view status_counts with distribution(hash(status))
select status, count(*) as total
from some_table
group by status
在一个不经常更新的大表上这样做是出于性能考虑。