请考虑以下付款数据:
customerID paymentID pamentType paymentDate paymentAmount
---------------------------------------------------------------------
1 1 A 2015-11-28 500
1 2 A 2015-11-29 -150
1 3 B 2016-03-07 300
2 4 A 2015-03-03 200
2 5 B 2016-05-25 -100
2 6 C 2016-06-24 700
1 7 B 2015-09-22 110
2 8 B 2016-01-03 400
我需要按照每位客户计算各种付款类型(A =发票,B =贷方通知单等)的总和,如下所示:
year customerID paymentType paymentSum
-----------------------------------------------
2015 1 A 350 : paymentID 1 + 2
2015 1 B 110 : paymentID 7
2015 1 C 0
2015 2 A 200 : paymentID 4
2015 2 B 0
2015 2 C 0
2016 1 A 0
2016 1 B 300 : paymentID 3
2016 1 C 0
2016 2 A 0
2016 2 B 300 : paymentID 5 + 8
2016 2 C 700 : paymentId 6
重要的是每个类别都有值(因此对于2015年,客户1对于C类有0个付款值,但仍然很高兴看到这个)。
实际上,有超过10种支付类型和约30个客户。总日期范围为10年。
这是否可以仅在SQL中执行,如果是这样,有人可以告诉我如何?如果可能的话,使用相对简单的查询,以便我可以从中学习,例如将中间结果存储到#temptable中。
非常感谢任何帮助!
答案 0 :(得分:3)
paymentAmount上带有SUM()的简单GROUP BY将为您提供所需的内容
select year = datepart(year, paymentDate),
customerID,
paymentType,
paymentSum = sum(paymentAmount)
from payment_data
group by datepart(year, paymentDate), customerID, paymentType
答案 1 :(得分:2)
这是一个生成所需0
的简单查询。请注意,它可能不是生成此结果集的最高效方式。如果您已经拥有客户或付款类型的查找表,那么最好使用那些而不是我在这里使用的CTE 1 :
declare @t table (customerID int,paymentID int,paymentType char(1),paymentDate date,
paymentAmount int)
insert into @t(customerID,paymentID,paymentType,paymentDate,paymentAmount) values
(1,1,'A','20151128', 500),
(1,2,'A','20151129',-150),
(1,3,'B','20160307', 300),
(2,4,'A','20150303', 200),
(2,5,'B','20160525',-100),
(2,6,'C','20160624', 700),
(1,7,'B','20150922', 110),
(2,8,'B','20160103', 400)
;With Customers as (
select DISTINCT customerID from @t
), PaymentTypes as (
select DISTINCT paymentType from @t
), Years as (
select DISTINCT DATEPART(year,paymentDate) as Yr from @t
), Matrix as (
select
customerID,
paymentType,
Yr
from
Customers
cross join
PaymentTypes
cross join
Years
)
select
m.customerID,
m.paymentType,
m.Yr,
COALESCE(SUM(paymentAmount),0) as Total
from
Matrix m
left join
@t t
on
m.customerID = t.customerID and
m.paymentType = t.paymentType and
m.Yr = DATEPART(year,t.paymentDate)
group by
m.customerID,
m.paymentType,
m.Yr
结果:
customerID paymentType Yr Total
----------- ----------- ----------- -----------
1 A 2015 350
1 A 2016 0
1 B 2015 110
1 B 2016 300
1 C 2015 0
1 C 2016 0
2 A 2015 200
2 A 2016 0
2 B 2015 0
2 B 2016 300
2 C 2015 0
2 C 2016 700
(如果上述日期处理需要能够使用索引,我们可能还希望玩数字表和/或生成多年的实际开始和结束日期)
另请注意我的脚本顶部与您问题中的示例数据有多相似 - 除了它是生成示例数据的实际代码。您可能希望考虑在将来以这种方式呈现示例代码,因为它简化了实际能够在答案中测试脚本的过程。
1 CTE - 通用表格表达式。它们可能被认为是概念上类似于临时表 - 除了我们实际上(必然)实现结果。它们也被合并到跟随它们的单个查询中,整个查询作为一个整体进行优化。
您建议使用临时表意味着您要将其分解为多个单独的查询,这些查询必然会强制SQL按我们选择的顺序执行任务,而不是让优化器为上述单个查询选择最佳方法。