【问题标题】:Calculating a summary of previously calculated data计算先前计算数据的摘要
【发布时间】:2013-12-04 07:20:44
【问题描述】:

关于汇总数据的快速问题:

我有以下代码,它将提取销售信息并将其放入月/年网格中,这太棒了 (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 列的底部

【问题讨论】:

    标签: sql summary


    【解决方案1】:

    问题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)
    

    【讨论】:

    • 您好 Guido,非常感谢您的回复,但我无法获得所提供的任何部分答案 - 您是否有机会使用 SQL 小提琴,看看您是否可以使其发挥作用在那个约束范围内?我应该提到它是 SQL server 2008
    • 完美运行!谢谢 Guido,你的 SQL 技能太棒了!
    • 谢谢,这是一个很好的练习。
    猜你喜欢
    • 1970-01-01
    • 2010-12-13
    • 1970-01-01
    • 2019-06-30
    • 2013-05-18
    • 1970-01-01
    • 1970-01-01
    • 2014-05-26
    • 2017-05-17
    相关资源
    最近更新 更多