我试着写一个简单的函数,它允许我根据列的值得到总和。
CREATE FUNCTION [GetSumOfColumnByCase](@column varchar(50), @case int)
RETURNS INT
AS
BEGIN
declare @return int
set @return = SUM(CASE WHEN @column = @case THEN 1 ELSE 0 END)
-- Return the result of the function
return @return
END
GO
我这样称呼这个函数:
SELECT HouseDescription,
[dbo].[GetSumOfColumnByCase]([HouseTypeId], 1) AS "houseType1",
[dbo].[GetSumOfColumnByCase]([HouseTypeId], 2) AS "houseType2"
以这种方式做事迫使我GROUP BY
使用houseDescription和HouseTypeId列,但我只想GROUP BY
进行内容描述。
如果我这样做:
SELECT HouseDescription,
SUM(CASE WHEN HouseTypeId = 1 THEN 1 ELSE 0 END) AS "houseType1",
SUM(CASE WHEN HouseTypeId = 2 THEN 1 ELSE 0 END) AS "houseType2"
很好,它不会强迫我GROUP BY
HouseTypeId。
任何人都可以解释为什么会这样吗?
答案 0 :(得分:2)
当您使用GROUP BY
子句时,每列都需要在GROUP BY中,或者需要聚合。
在您的第二个示例中,您通过在函数调用周围放置SUM
来满足这些要求。在您的第一个示例中,由于函数调用本身并未包含在聚合(SUM
,MAX
,MIN
等)中,因此您必须将其放在GROUP BY中子句,以便不触发错误。
https://msdn.microsoft.com/en-us/library/ms177673.aspx
我同意戈登的意见,你可能想重新考虑一下这个策略。
答案 1 :(得分:0)
您无法使用函数执行所需操作,因为SQL Server在函数中不支持动态SQL(很容易)。要处理任何列,您需要动态SQL。
但是,无论如何你都不需要。如果您想要原始数据的每一行的总和,您需要窗口函数:
SELECT SUM(CASE WHEN HouseTypeId = 1 THEN 1 ELSE 0 END) OVER () AS houseType1,
SUM(CASE WHEN HouseTypeId = 2 THEN 1 ELSE 0 END) OVER () AS houseType2
. . .
此查询不需要聚合。