我在 SQL Server 数据库中有以下 2 个表。
客户主要费用表
ReportID CustomerID TotalExpenseAmount
1000 1 200
1001 2 600
与会者表
ReportID AttendeeName
1000 Mark
1000 Sam
1000 Joe
与会者级别没有金额。我需要手动计算个人与会者数量,如下所述。 (即根据参加者人数拆分 TotalExpenseAmount,并确保各个拆分数字四舍五入到小数点后两位,总和精确等于 TotalExpenseAmount)
最终报告应如下所示:
ReportID CustID AttendeeName TotalAmount AttendeeAmount
1000 1 Mark 200 66.66
1000 1 Sam 200 66.66
1000 1 Joe 200 66.68
最终报告将包含大约 1,50,000 条记录。如果您注意到与会者数量,我已将最后一个数字四舍五入,使总数匹配到 200。在这种情况下编写高效 SQL 查询的最佳方法是什么?
最佳答案
您可以使用窗口函数来做到这一点:
select ReportID, CustID, AttendeeName, TotalAmount,
(case when seqnum = 1
then TotalAmount - perAttendee * (cnt - 1)
else perAttendee
end) as AttendeeAmount
from (select a.ReportID, a.CustID, a.AttendeeName, e.TotalAmount,
row_number() over (partition by reportId order by AttendeeName) as seqnum,
count(*) over (partition by reportId) as cnt,
cast(TotalAmount * 1.0 / count(*) over (partition by reportId) as decimal(10, 2)) as perAttendee
from attendee a join
expense e
on a.ReportID = e.ReportID
) ae;
perAttendee
金额在子查询中计算。这是通过使用 cast()
向下舍入的(仅因为 floor()
不接受小数位数参数)。对于其中一行,金额是总数减去所有其他与会者的总和。
关于SQL Server 数量拆分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34453508/