Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL查询按月求和,并将年作为列_Sql_Sql Server 2008 - Fatal编程技术网

SQL查询按月求和,并将年作为列

SQL查询按月求和,并将年作为列,sql,sql-server-2008,Sql,Sql Server 2008,我有以下疑问 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(P

我有以下疑问

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年数据)

如何透视数据并添加计算列

提前感谢。

您可以使用加入

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'

使用条件聚合:

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);

另一种选择是将枢轴与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]
返回


通过使用一个案例语句创建一个子查询,该子查询按月份分组,并按年份分隔付款:

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

答案取决于您未能指定的数据库引擎。SQL server2008@NickKester然后在您的问题中添加
SQL Server
标记。仅两年或更长时间?实际上,此报告将持续进行。将需要2017年和2018年的比较。cte给出了一个错误:ORDER BY子句在视图、内联函数、派生表、子查询和公共表表达式中无效,除非还指定了TOP或FOR XML。@NickKester抱歉,请删除ORDER BY。我只是简单地粘贴了原件query@NickKester更新了答案并在最终选择中添加了Order By。我发现一个语法错误:关键字“Pivot”附近的语法不正确。@NickKester请参阅更新。在我这方面,草率的复制粘贴。将别名“A”添加到子查询中