如何编写SQL以获取累积值和每行总计?

时间:2013-07-16 09:28:01

标签: sql oracle analytic-functions

说,我有以下数据:

  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来获得此结果?

3 个答案:

答案 0 :(得分:6)

尝试这种方式:

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


更多信息

答案 1 :(得分: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

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

答案 2 :(得分:2)

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

    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