计算先前计算的数据的摘要

时间:2013-12-04 07:20:45

标签: sql summary

关于摘要数据的快速提问:

我有以下代码,它将提取销售信息并将其放入月/年网格中,这非常棒(http://sqlfiddle.com/#!3/9d79e/1):

WITH 
months AS (SELECT 1 AS mon UNION ALL SELECT mon + 1 FROM months WHERE mon < 12),
years AS (SELECT 2011 AS yr UNION ALL SELECT yr + 1 FROM years WHERE yr < 2015),
invoices AS (
SELECT CAST('2013-06-27' AS date) AS InvoiceDate, 40 AS MarginAmount
UNION 
SELECT CAST('2013-07-29' AS date) AS InvoiceDate, 40 AS MarginAmount
UNION 
SELECT CAST('2013-10-30' AS date) AS InvoiceDate, 40 AS MarginAmount
)

-- End data setup, real work begins here
SELECT * FROM
(
SELECT 
months.mon, years.yr, COALESCE(SUM(inv.MarginAmount), 0) AS MarginAmount
FROM 
months
CROSS JOIN years 
LEFT OUTER JOIN invoices inv ON ( (YEAR(inv.InvoiceDate) = years.yr) AND   (MONTH(inv.InvoiceDate) = months.mon) )
GROUP BY 
months.mon, years.yr 
) AS source 
PIVOT
(
MAX(MarginAmount)
FOR yr in ([2011], [2012], [2013], [2014], [2015])
)
AS pvt  
ORDER BY mon

我想知道如何改变两件事:

Replace the numbers 1 - 11 with the names of the months of the year and

Create a line at the bottom of the table summarizing the information above it, where the mon column would have the word 'Total'

非常感谢任何帮助

例如,2012年所有销售额的总和将显示在2012年专栏的底部

1 个答案:

答案 0 :(得分:0)

问题1.替换数字

要替换这些数字,您可以更改一下:

months AS (SELECT 1 AS mon UNION ALL SELECT mon + 1 FROM months WHERE mon < 12)

months AS (SELECT 1 AS mon, 'Jan' name UNION ALL SELECT mon + 1, months.name FROM months WHERE mon < 12)

问题2.总计

要创建总计的底线,您可以使用分组集(您的查询似乎是SQL Server,不知道SQL Server是否支持,请指定):

group
by    grouping sets
      ( ()
      , (full list)
      )

或在查询中添加联合:

with myresults as (the whole thing)
select 1 ordering
,      myresults.columns-minus-total
,      myresults.something subtotal
from   myresults
union all
select 2 ordering
,      myresults.columns-minus-total
,      sum(something) grandtotal
from   myresults
order
by     1
,      ...other...

使用Microsoft SQL Server 2008 R2的完整示例

原始代码被美化并且不依赖于表:

with months as 
( select 1 as mon 
  ,      'Jan' monname
  union all 
  select 2
  ,      'Feb'
  union all 
  select 3
  ,      'Mar'
  union all 
  select 4
  ,      'Apr'
  union all 
  select 5
  ,      'May'
  union all 
  select 6
  ,      'Jun'
  union all 
  select 7
  ,      'Jul'
  union all 
  select 8
  ,      'Aug'
  union all 
  select 9
  ,      'Sep'
  union all 
  select 10
  ,      'Oct'
  union all 
  select 11
  ,      'Nov'
  union all 
  select 12
  ,      'Dec'
)
, years as 
  ( select 2011 as yr 
    union all 
    select 2012 
    union all 
    select 2013
    union all 
    select 2014
  )
, invoices as 
  ( select cast('2013-06-27' as date) as invoicedate
    ,      40 as marginamount
    union 
    select cast('2013-07-29' as date) as invoicedate
    ,      40 as marginamount
    union 
    select cast('2013-10-30' as date) as invoicedate
    ,      40 as marginamount
  )
select * 
from   ( select months.mon
         ,      years.yr
         ,      coalesce(sum(inv.marginamount), 0) as marginamount
         from   months
         cross 
         join   years 
         left 
         outer 
         join   invoices inv 
         on     year(inv.invoicedate)  = years.yr
         and    month(inv.invoicedate) = months.mon
         group 
         by     months.mon
         ,      years.yr 
       ) source 
pivot  ( max(marginamount)
         for yr 
         in  ( [2011], [2012], [2013], [2014], [2015]
             )
       ) pvt  
order 
by     mon

添加文字和总计会导致:

with months as 
( select 1 as mon 
  ,      'Jan' monname
  union all 
  select 2
  ,      'Feb'
  union all 
  select 3
  ,      'Mar'
  union all 
  select 4
  ,      'Apr'
  union all 
  select 5
  ,      'May'
  union all 
  select 6
  ,      'Jun'
  union all 
  select 7
  ,      'Jul'
  union all 
  select 8
  ,      'Aug'
  union all 
  select 9
  ,      'Sep'
  union all 
  select 10
  ,      'Oct'
  union all 
  select 11
  ,      'Nov'
  union all 
  select 12
  ,      'Dec'
)
, years as 
  ( select 2011 as yr 
    union all 
    select 2012 
    union all 
    select 2013
    union all 
    select 2014
  )
, invoices as 
  ( select cast('2013-06-27' as date) as invoicedate
    ,      40 as marginamount
    union 
    select cast('2013-07-29' as date) as invoicedate
    ,      40 as marginamount
    union 
    select cast('2013-10-30' as date) as invoicedate
    ,      40 as marginamount
  )
select case
       when mon is null
       then 'Total'
       else cast(mon as varchar)
       end
,      monname
,      [2011]
,      [2012]
,      [2013]
,      [2014]
,      [2015]
from   ( select months.mon
         ,      months.monname
         ,      years.yr
         ,      coalesce(sum(inv.marginamount), 0) as marginamount
         from   months
         cross 
         join   years 
         left 
         outer 
         join   invoices inv 
         on     year(inv.invoicedate)  = years.yr
         and    month(inv.invoicedate) = months.mon
         group
         by     grouping sets
                ( (months.mon, months.monname, years.yr)
                , (years.yr)
                )
       ) source 
pivot  ( max(marginamount)
         for yr 
         in  ( [2011], [2012], [2013], [2014], [2015]
             )
       ) pvt  
order 
by     coalesce(mon, 100)