我有以下查询
SELECT
MONTH(PaymentDate) AS [month],
YEAR(PaymentDate) AS [year],
SUM(OutstandingPayment) AS totalCollected
FROM
Payments
WHERE
PaymentDate BETWEEN '01/01/2016' AND '12/31/2017'
GROUP BY
YEAR(PaymentDate), MONTH(PaymentDate)
ORDER BY
YEAR(PaymentDate), MONTH(PaymentDate)
输出低于
month year totalCollected
----------------------------------
1 2016 10000
2 2016 11000
3 2016 12000
4 2016 13000
5 2016 14000
6 2016 15000
7 2016 16000
8 2016 17000
9 2016 18000
10 2016 19000
11 2016 20000
12 2016 21000
1 2017 11000
2 2017 12000
3 2017 13000
4 2017 14000
5 2017 15000
6 2017 16000
7 2017 17000
8 2017 18000
9 2017 19000
10 2017 20000
11 2017 21000
12 2017 22000
我希望输出为
Month 2016 2017 $Change %Change
----------------------------------------
1 10000 11000 1000 10.00%
2 11000 12000 1000 9.09%
3 12000 13000 1000 8.33%
4 13000 14000 1000 7.69%
5 14000 15000 1000 7.14%
6 15000 16000 1000 6.67%
7 16000 17000 1000 6.25%
8 17000 18000 1000 5.88%
9 18000 19000 1000 5.56%
10 19000 20000 1000 5.26%
11 20000 21000 1000 5.00%
12 21000 22000 1000 4.76%
$change
是2017年数据 - 2016年数据。变化百分比为((2016年数据 - 2017年数据)/ 2017年数据)。
如何透视数据并添加计算列?
提前致谢。
答案 0 :(得分:1)
使用条件聚合:
select month(PaymentDate) as [month],
sum(case when year(PaymentDate) = 2016 then OutstandingPayment end) as totalCollected_2016,
sum(case when year(PaymentDate) = 2017 then OutstandingPayment end) as totalCollected_2017,
sum(case when year(PaymentDate) = 2017 then OutstandingPayment
when year(PaymentDate) = 2016 then -OutstandingPayment
end) as diff,
( (sum(case when year(PaymentDate) = 2017 then OutstandingPayment end) /
sum(case when year(PaymentDate) = 2016 then OutstandingPayment end)
) - 1
) as increase
from Payments p
where PaymentDate BETWEEN '2016-01-01' AND '2017-12-31'
group by month(PaymentDate)
order BY month(PaymentDate);
答案 1 :(得分:1)
另一种选择是将PIVOT与CTE协调一致
示例强>
;with cte as (
Select *
From (
select month(PaymentDate) as [month], year(PaymentDate) as [year], sum(OutstandingPayment) as totalCollected
FROM Payments
WHERE PaymentDate BETWEEN '01/01/2016' AND '12/31/2017'
group by year(PaymentDate), month(PaymentDate)
) A
Pivot (sum(totalCollected) for year in ([2016],[2017]) ) pvt
)
Select *
,[$Change] = [2017]-[2016]
,[%Change] = (([2017]-[2016])*100) / NullIf([2016],0)
From cte
Order By [month]
<强>返回强>
答案 2 :(得分:0)
您可以使用联接
select a. month
, a.totalCollected
, b.totalCollected - a.totalCollected as ` $Change`
, ( b.totalCollected - a.totalCollected) / a.totalCollected ` %Change`
from my_table ainner join my_table b on a.month = b.month and a.year = '2016' and b.year = '2017'
select a. month
, a.totalCollected
, b.totalCollected - a.totalCollected as ` $Change`
, ( b.totalCollected - a.totalCollected) / a.totalCollected ` %Change`
from (
select month(PaymentDate) as [month], year(PaymentDate) as [year], sum(OutstandingPayment) as totalCollected
FROM Payments
WHERE PaymentDate BETWEEN '01/01/2016' AND '12/31/2017'
group by year(PaymentDate), month(PaymentDate)
ORDER BY year(PaymentDate), month(PaymentDate)
) a
inner join (
select a. month
, a.totalCollected
, b.totalCollected - a.totalCollected as ` $Change`
, ( b.totalCollected - a.totalCollected) / a.totalCollected ` %Change`
from my_table ainner join my_table b on a.month = b.month and a.year = '2016' and b.year = '2017'
) b on a.month = b.month and a.year = '2016' and b.year = '2017'
您可以使用视图来避免代码重复
create view my_view as
select month(PaymentDate) as [month], year(PaymentDate) as [year], sum(OutstandingPayment) as totalCollected
FROM Payments
WHERE PaymentDate BETWEEN '01/01/2016' AND '12/31/2017'
group by year(PaymentDate), month(PaymentDate)
ORDER BY year(PaymentDate), month(PaymentDate)
select a. month
, a.totalCollected
, b.totalCollected - a.totalCollected as ` $Change`
, ( b.totalCollected - a.totalCollected) / a.totalCollected ` %Change`
from (
my_view
) a
inner join (
my_view
) b on a.month = b.month and a.year = '2016' and b.year = '2017'
答案 3 :(得分:0)
通过使用按月分组的子查询,并使用case语句按年份分隔付款:
SELECT [month],
[2016_TOTAL] as [2016],
[2017_TOTAL] as [2017],
([2017_TOTAL] - [2016_TOTAL]) as [$Change]
(([2016_TOTAL] - [2017_TOTAL])/[2017_TOTAL]) as [%Change]
FROM
(
SELECT
MONTH(PaymentDate) AS [month],
SUM(CASE WHEN YEAR(PaymentDate)='2016' then OutstandingPayment) AS [2016_TOTAL],
SUM(CASE WHEN YEAR(PaymentDate)='2017' then OutstandingPayment) AS [2017_TOTAL]
FROM
Payments
WHERE
PaymentDate BETWEEN '01/01/2016' AND '12/31/2017'
GROUP BY
MONTH(PaymentDate)
) temp