划分分区以按月累计数据

时间:2014-10-10 14:59:45

标签: sql tsql window-functions

我有一些数据,我需要每个月汇总,我很难弄清楚如何让它有12列(每月一列)与该月的总和。

示例:

数据原样:

GrossAmt    ClaimDate
49764.00    2014-08-21 00:00:00.000
1382.43     2014-08-27 00:00:00.000
602.77      2014-09-02 00:00:00.000
497.04      2014-09-02 00:00:00.000

期望的结果:

GrossAmt    ClaimDate
51146.43    August
1099.81     September

实际所需结果:

July  August    September
0     51146.43  1099.81

对不起,我之前没有包括这个!

我确信这是使用行分区的最基本的例子,也许是我缺乏编程背景,但这是一个我无法理解的概念。

这是我到目前为止所做的,但我不知道下一步该怎么做。

With CTE ([GrossAmt],ClaimMonth)
AS(
SELECT TOP 10000 
       Sum([GrossAmt]) as TotalClaimAmt
      ,CASE WHEN Month([ClaimDate]) = 1 THEN 'January'
            WHEN Month([ClaimDate]) = 2 THEN 'February'
            WHEN Month([ClaimDate]) = 3 THEN 'March'
            WHEN Month([ClaimDate]) = 4 THEN 'April'
            WHEN Month([ClaimDate]) = 5 THEN 'May'
            WHEN Month([ClaimDate]) = 6 THEN 'June'
            WHEN Month([ClaimDate]) = 7 THEN 'July'
            WHEN Month([ClaimDate]) = 8 THEN 'August'
            WHEN Month([ClaimDate]) = 9 THEN 'September'
            WHEN Month([ClaimDate]) = 10 THEN 'October'
            WHEN Month([ClaimDate]) = 11 THEN 'November'
            WHEN Month([ClaimDate]) = 12 THEN 'Decmber'
        End  AS ClaimMonth
  FROM [Database].[dbo].[Table]
    )
    Group BY  [ClaimDate]
    )
  Select * From CTE

也许我可能需要的是关于Row over partition如何工作的基本教训。我曾尝试阅读我在网上找到的文章,但似乎没有一个对我有意义,他们是先进的方式,我马上就迷路了,而且通过阅读我不能很好地学习也无济于事,我需要看到它在行动,并了解它是如何工作的。

无论如何,谢谢你的帮助。你们好棒! 编辑:

实际所需结果:

July  August    September
0     51146.43  1099.81

对不起我之前没有包括这个!

4 个答案:

答案 0 :(得分:2)

您需要使用PIVOT来获得所需的结果

CTE正在进行每月聚合,PIVOT用于将CTE结果行转换为水平列

;With CTE ([GrossAmt],MonthVal)
AS(
SELECT TOP 10000 
       Sum([GrossAmt]) as GrossAmt,
       DATEADD(MONTH, DATEDIFF(MONTH,0,ClaimDate), 0) as MonthVal
  FROM [Table1]
  Group BY  DATEADD(MONTH, DATEDIFF(MONTH,0,ClaimDate), 0)
)
SELECT * FROM
(Select [GrossAmt], DATENAME(MONTH,MonthVal) as ClaimMonth From CTE) t
PIVOT
( MAX(GrossAmt) for ClaimMonth  in 
  ( [January], [Febrauary], [March], [April], [May], [June], [July],  
    [August],  [September], [October], [November], [December] 

  )
)pvt

答案 1 :(得分:0)

DECLARE @Cols NVARCHAR(MAX);
SELECT @Cols =  STUFF((
                SELECT DISTINCT ', ' +  QUOTENAME(DATENAME(MONTH,ClaimDate))
                FROM TABLENAME
                FOR XML PATH(''), TYPE).value('.','NVARCHAR(MAX)'),1,2,'')
DECLARE @Sql NVARCHAR(MAX);

SET @Sql  = 'SELECT ''GrossAmount'' AS AMOUNT_Sorted_By_DATE, 
' + @Cols +   '
FROM
(SELECT [GrossAmt], DATENAME(MONTH,ClaimDate) as ClaimMonth
FROM TABLENAME GROUP BY MONTH(ClaimDate)) AS SourceTable
PIVOT
(
SUM(GrossAmt)
FOR DATENAME(MONTH,ClaimDate) IN (' + @Cols +   ')
) AS PivotTable'
EXECUTE sp_executesql @Sql    

这将导致仅实际拥有数据的月数。

答案 2 :(得分:-1)

With CTE ([GrossAmt],ClaimMonth)
AS(
SELECT TOP 10000 
       Sum([GrossAmt]) as TotalClaimAmt
      ,DATENAME(MONTH, ClaimDate) AS ClaimMonth
  FROM [Database].[dbo].[Table]
  Group BY  DATENAME(MONTH, ClaimDate)
)
Select * From CTE

答案 3 :(得分:-1)

select top 1000 
       datename(month, [ClaimDate]), SUM([GrossAmt]) 
  from [Table] 
 group by datename(month, [ClaimDate])