【问题标题】:How do I write an SQL to get a cumulative value and a monthly total in one row?如何编写 SQL 以在一行中获取累积值和每月总计?
【发布时间】:2013-07-16 09:28:00
【问题描述】:

说,我有以下数据:

  select 1 id, date '2007-01-16' date_created, 5 sales, 'Bob' name from dual union all
  select 2 id, date '2007-04-16' date_created, 2 sales, 'Bob' name from dual union all
  select 3 id, date '2007-05-16' date_created, 6 sales, 'Bob' name from dual union all
  select 4 id, date '2007-05-21' date_created, 4 sales, 'Bob' name from dual union all
  select 5 id, date '2013-07-16' date_created, 24 sales, 'Bob' name from dual union all
  select 6 id, date '2007-01-17' date_created, 15 sales, 'Ann' name from dual union all
  select 7 id, date '2007-04-17' date_created, 12 sales, 'Ann' name from dual union all
  select 8 id, date '2007-05-17' date_created, 16 sales, 'Ann' name from dual union all
  select 9 id, date '2007-05-22' date_created, 14 sales, 'Ann' name from dual union all
  select 10 id, date '2013-07-17' date_created, 34 sales, 'Ann' name from dual

我想得到如下结果:

Name        Total_cumulative_sales      Total_sales_current_month
Bob         41                          24
Ann         91                          34

在此表中,对于 Bob,他的总销售额从一开始就是 41。而对于这个月,也就是 7 月,他整个月的销售额是 24。Ann 也是如此。

如何编写 SQL 来得到这个结果?

【问题讨论】:

    标签: sql oracle analytic-functions


    【解决方案1】:

    试试这个方法:

    select name, sum(sales) as Total_cumulative_sales ,
           sum( 
                case trunc(to_date(date_created), 'MM')
                  when  trunc(sysdate, 'MM') then sales
                  else 0
                end
            ) as  Total_sales_current_month
    
    from tab
    group by name
    

    SQL 小提琴 Demo


    更多信息

    【讨论】:

    • 我认为这增加了同月但不同年份的销售额。这是想要的吗?
    • @Darkzaelus See this link 我已将第一行更改为2007-07-16,它仍然有效
    • 然后我撤回,道歉 :) 我必须阅读 trunc 函数来弄清楚它是如何工作的
    • 哦哦,它不只是带回月份,它还返回日期和任何其他不太相关的数据,基本上四舍五入。聪明
    【解决方案2】:
    SELECT Name, 
    SUM(Sales) Total_sales, 
    SUM(CASE WHEN MONTH(date_created) = MONTH(GetDate()) AND YEAR(date_created) = YEAR(GetDate()) THEN Sales END) Total_sales_current_month
    GROUP BY Name
    

    应该可以,但可能有一种更优雅的方式来指定“在当前月份”。

    【讨论】:

      【解决方案3】:

      这应该适用于多年的销售。它将获得任意年的累计销售额。如果最近一个月没有销售,则不会产生记录。

          WITH sales AS 
      (select 1 id, date '2007-01-16' date_created, 5 sales, 'Bob' sales_name from dual union all
        select 2 id, date '2007-04-16' date_created, 2 sales, 'Bob' sales_name from dual union all
        select 3 id, date '2007-05-16' date_created, 6 sales, 'Bob' sales_name from dual union all
        select 4 id, date '2007-05-21' date_created, 4 sales, 'Bob' sales_name from dual union all
        select 5 id, date '2013-07-16' date_created, 24 sales, 'Bob' sales_name from dual union all
        select 6 id, date '2007-01-17' date_created, 15 sales, 'Ann' sales_name from dual union all
        select 7 id, date '2007-04-17' date_created, 12 sales, 'Ann' sales_name from dual union all
        select 8 id, date '2007-05-17' date_created, 16 sales, 'Ann' sales_name from dual union all
        select 9 id, date '2007-05-22' date_created, 14 sales, 'Ann' sales_name from dual union all
        select 10 id, date '2013-07-17' date_created, 34 sales, 'Ann' sales_name from dual)
        SELECT  sales_name
               ,total_sales
               ,monthly_sales
               ,mon 
        FROM (SELECT sales_name
                    ,SUM(sales) OVER (PARTITION BY sales_name ORDER BY mon) total_sales
                    ,SUM(sales) OVER (PARTITION BY sales_name,mon ORDER BY mon) monthly_sales
                    ,mon 
                    ,max_mon
              FROM (  SELECT sales_name
                            ,sum(sales) sales
                            ,mon
                            ,max_mon
                      FROM   (SELECT sales_name
                                    ,to_number(to_char(date_created,'YYYYMM')) mon
                                    ,sales
                                    ,MAX(to_number(to_char(date_created,'YYYYMM'))) OVER (PARTITION BY sales_name) max_mon
                              FROM sales
                              ORDER BY 2)
                      GROUP BY sales_name
                              ,max_mon
                              ,mon
                   )
              )
      WHERE max_mon = mon
      

      ;

      【讨论】:

        猜你喜欢
        • 2021-03-16
        • 2021-10-11
        • 1970-01-01
        • 2018-06-28
        • 1970-01-01
        • 2021-07-22
        • 2021-10-31
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多