按年,月和累计金额排序

时间:2016-05-18 21:03:12

标签: sql-server-2012

我的桌子" DATA123"如下

NoticeDate------Amount
2016-02-14------60000
2015-11-06------10000
2015-12-02------10000
2016-01-13------50000
2016-01-24------10000
2015-12-29------30000
2016-01-12------20000
2015-11-18------50000

我希望输出为

Year----month----Amount----Cumulative
2015----NOV------60000------60000
2015----DEC------40000------100000
2016----JAN------80000------180000
2016----FEB------60000------240000

总之,我想要有序的月度报告sql查询(不是程序)与累积总和。但是,我没有代表每条记录的唯一ID。

4 个答案:

答案 0 :(得分:2)

由于您使用的是2012,因此这是使用window functions的一个选项:

select
    yr,
    mth,
    sumamount,
    sum(sumamount) over (order by yr, mth rows unbounded preceding) runningsum
from (select year(noticedate) yr,
             month(noticedate) mth,
            sum(amount) sumamount
      from data123
      group by year(noticedate), month(noticedate)
) t
order by yr, mth

答案 1 :(得分:1)

我建议这个查询:

select datepart(year, NoticeDate1) Year,
       format(NoticeDate1,'MMM') Month,
       Amount,
       sum(Amount) over (order by NoticeDate1
                         rows unbounded preceding) Cumulative
from (
    select   dateadd(month, datediff(month, 0, NoticeDate), 0) NoticeDate1,
             sum(amount) Amount
    from     data123
    group by dateadd(month, datediff(month, 0, NoticeDate), 0)
) a

它为样本数据生成此输出:

| Year | Month | Amount | cumulative |
|------|-------|--------|------------|
| 2015 |   Nov |  60000 |      60000 |
| 2015 |   Dec |  40000 |     100000 |
| 2016 |   Jan |  80000 |     180000 |
| 2016 |   Feb |  60000 |     240000 |

SQL fiddle

查询使用带有rows unbounding preceding的窗口函数,这是累积和的关键。 NoticeData1是该日期NoticeDate的第一天。 format函数可用于获取月份名称。

您可能想要添加order by子句,但最好选择月份编号,因为月份名称不会像您想要的那样排序:)。排序顺序仍然像现在一样好。引擎需要累积总和的正确排序顺序,因此没有理由对其进行更改。

答案 2 :(得分:0)

您可以使用DATEPART或DATENAME功能,并使用ROW_NUMBER生成行号:

SELECT A.DataRowNumber, A.[year], A.[month], A.[day], A.[Ammount], SUM(B.[Ammount]) FROM (SELECT ROW_NUMBER() OVER (ORDER BY [NoticeDate]) AS 'DataRowNumber', DATEPART(YEAR, [NoticeDate]) AS 'year',DATENAME(MONTH, [NoticeDate]) AS 'month', DATEPART(DAY, [NoticeDate]) AS 'day',[Ammount]
      FROM [dbo].[DATA123]) A INNER JOIN (SELECT ROW_NUMBER() OVER (ORDER BY [NoticeDate]) AS 'DataRowNumber', DATEPART(YEAR, [NoticeDate]) AS 'year',DATENAME(MONTH, [NoticeDate]) AS 'month', DATEPART(DAY, [NoticeDate]) AS 'day',[Ammount]
      FROM [dbo].[DATA123]) B
ON A.[DataRowNumber] >= B.[DataRowNumber]
GROUP BY A.[DataRowNumber], A.[year], A.[month], A.[day], A.[peso_factura]

答案 3 :(得分:0)

使用WITH关键字,执行以下查询:

WITH cte AS 
( 
    SELECT  YEAR(NoticeDate) AS [Year], 
            Month(NoticeDate) AS [Month], 
            Amount 
    FROM    DATA123 
), 

kte AS 
( 
    SELECT  ROW_NUMBER() OVER (ORDER BY [Year], [Month]) as RowNumber, 
            [Year], 
            [Month], 
            SUM(Amount) AS Amount 
    FROM    cte 
    GROUP   BY [Year], [Month] 
) 

SELECT  (SELECT [Year]  FROM kte WHERE RowNumber = t1.RowNumber) AS [Year],
        (SELECT UPPER(CONVERT(CHAR(3), CAST('2000-' + CAST((SELECT [Month]  FROM kte WHERE RowNumber = t1.RowNumber) AS NVARCHAR(2)) + '-01' AS DATE), 0)))  AS [Month], 
        t1.Amount, 
        SUM(t2.Amount) AS Cumulative 
FROM    kte t1 
JOIN    kte t2 ON t1.RowNumber >= t2.RowNumber 
GROUP   By t1.RowNumber, t1.Amount 
ORDER   BY t1.RowNumber 


通过执行上述查询,应获得以下结果:

+-------------------------------------+
| Year | Month |  Amount | Cumulative |
|------+-------+---------+------------+
| 2015 |  NOV  |  60000  |   60000    |
| 2015 |  DEC  |  40000  |   100000   |
| 2016 |  JAN  |  80000  |   180000   |
| 2016 |  FEB  |  60000  |   240000   |
+-------------------------------------+