在这里,我尝试计算特定学生在特定会计年度以及该会计年度的每个月为学费支付的SUM
。
例如,下面的行PaidTutionFee
由SUM(Tution) AS PaidTutionFee
计算。现在我要对PaidTutionFee
列求和,
StudentId FYID Month PaidTutionFee
7 16 3 2855.00
7 16 4 2855.00
为此,我已经计算了学费,即SUM(Tution) AS PaidTutionFee
并按StudentId, FYId, Month
分组,这将得出该会计年度每个月的Tution之和,最后是我拥有的整个会计年度的总Tution对SUM(Tution) AS PaidTutionFee
的别名即SUM(PaidTutionFee) AS TotalTutionFeeInFiscalYear
求和。
现在的问题是我抛出一个错误,说
Msg 207, Level 16, State 1, Line 11
Invalid column name 'PaidTutionFee'.
以下是我的SQL Server查询
SELECT StudentId,FYId, Month, SUM(Tution) AS PaidTutionFee,
SUM(PaidTutionFee) AS TotalTutionFeeInFiscalYear
FROM [dbo].[FeePaymentDetails]
WHERE FYId = 16 AND StudentId = 7
GROUP BY StudentId, FYId, Month
答案 0 :(得分:1)
您不能在同一条SELECT语句中聚合一个聚合。但是...这并不是您真正想要的。如果要按tuition
分组,则要StudentID, FYid, Month
的总和,如果要按tuition
分组,则要StudentID, FYid
的总和(如果我没看错)。为此,您可以使用窗口功能:
SELECT StudentId,FYId, Month, SUM(Tution) AS PaidTutionFee
Sum(Tution) OVER (PARTITION BY SutdentID, FyID) as TotalTutionFeeInFiscalYear
FROM [dbo].[FeePaymentDetails]
WHERE FYId = 16 AND StudentId = 7
GROUP BY StudentId, FYId, Month;
现在,您的结果集的粒度位于StudentId, FYId, Month
级别,但是您还有一个额外的列,该列的值针对每个不同的StudentId, FYId
重复,并且其值表示该级别的更高粒度的总和你在追。
答案 1 :(得分:1)
sqlserver备受赞赏的汇总和分组集功能可以很容易地做到这一点:
SELECT StudentId,FYId, Month, SUM(Tution) AS PaidTutionFee
Sum(Tution) OVER (PARTITION BY SutdentID, FyID) as TotalTutionFeeInFiscalYear
FROM [dbo].[FeePaymentDetails]
/*WHERE FYId = 16 AND StudentId = 7*/
GROUP BY ROLLUP(StudentId, FYId, Month)
我选择ROLLUP是因为我认为这最容易理解
Sqlserver将按照您的要求进行分组,直到月级,这样您每个月都会得到一行。然后,由于添加了ROLLUP,您将获得一个带有NULL月份的行,这是学生/年的所有内容的总和。您还将获得一行,其中月份和年份为空,这是该学生的总和;一行所有空值,这是所有学生的总计。因此,结果是,分组/汇总从最精确的(学生/年/月/月)“累积”到最不精确的(所有值的总和),按从右到左的顺序(取决于组中列的顺序)由
我注释了您的where子句,以更好地演示汇总效果-如果将其放回去,您将获得一些总计行,这些行与您已经知道的行没有什么不同(因为只有一名学生和一年,所以所有学生的总数将与一个学生的总数相同,等等)
GROUPING SETS使您可以更好地微调小计/大计效果
如果您是通过这样的方式组建的:
GROUP BY GROUPING SETS((StudentId,FyId,Month),(StudentId,FyId))
由于第二个分组集,您将只获得月份的详细信息(由于第一个分组集)和月份为空的行(该年度的第三个总数)
答案 2 :(得分:0)
您可以使用Partition By来计算运行总计和总计,而无需按以下方式分组:
SELECT StudentId,FYId, Month, SUM(Tuition) over (partition by StudentId, FyId) AS PaidTutionFee,
SUM(Tution) over (partition by StudentId, Year(FyId)) AS TotalTutionFeeInFiscalYear
FROM [dbo].[FeePaymentDetails]
WHERE FYId = 16 AND StudentId = 7
Order BY StudentId, FYId, Month