在Oracle SQL中按周汇总数据

时间:2014-01-23 16:33:21

标签: sql oracle

我有一个Oracle表(Oracle 11g),其中包含数小时的加班时间(WRK_HR)和工作日期(CHRG_DT)。我想构建一个存储过程,它返回从项目开始到提供日期的每周五星期六到星期五的WRK_HR总和。说我的表包含以下内容:

CHRG_DT   WRK_HR
--------  ------
01/01/14       4
01/02/14       8
01/15/14       7

我的输出应该如下(每个日期是星期五):

CHRG_DT   TOTAL
--------  -----
01/03/14     12
01/10/14     12
01/17/14     19

这是我的SQL:

PROCEDURE GET_OVERTIME(  
  p_chrg_dt IN VARCHAR2,  
  cur OUT sys_refcursor  
)  
IS  
BEGIN  
OPEN cur FOR  
  SELECT  
  TO_CHAR(CHRG_DT, 'mm/dd/yyyy') AS CHRG_DT,  
  SUM(WRK_HR) AS TOTAL  
  FROM OVERTIME
  WHERE TRUNC(CHRG_DT) <= TO_DATE(p_chrg_dt, 'mm/dd/yyyy')
  GROUP BY CHRG_DT
  ORDER BY CHRG_DT;
END; 

这是我的SQL的结果。如您所见,它为每个独特的日子提供了一个结果。即使星期五没有参赛作品,我也需要在每个星期五进行总计:

CHRG_DT   TOTAL
--------  -----
01/01/14      4
01/02/14     12
01/15/14     19

2 个答案:

答案 0 :(得分:3)

您只需将日期值转换为星期结束,然后按该值进行选择和分组。

从他们减去一天,并使用NEXT_DAY()来获得下一个星期五...

NEXT_DAY(CHRG_DT-1,'FRIDAY')

答案 1 :(得分:1)

使用这组测试数据......

 create table tq84_sum_data_by_week (
   chrg_dt   date,
   wrk_hr    number
 );

 insert into tq84_sum_data_by_week values (date '2014-01-01', 4);
 insert into tq84_sum_data_by_week values (date '2014-01-02', 8);
 insert into tq84_sum_data_by_week values (date '2014-01-15', 7);

......以下应该做:

 with fridays as (
 --
 -- 1 First, we need to "create" all fridays that we want
 --   the report to sum on
 --
   select
 --
 -- 2 The first friday is 01/03/14
 --
     date '2014-01-03' + 
 --
 -- 3  The fridays are 7 days apart:
 --
    (level-1) * 7 date_
 --
   from dual
 --
 -- 4  Three fridays are sufficient
 --    for this small test.
 --
     connect by level <= 3
 )
 --
 select 
   fridays.date_,
 --
 -- 7  This expression does the 'cumulative sum':
 --
   sum(sum(weeks.wrk_hr)) over (order by fridays.date_)  total_hrs
 from 
 --
 -- 5  Since we want a record for *each* friday,
 --    we use a 'left join':
 --
   fridays               left   outer join
 --
   tq84_sum_data_by_week weeks
 --
 -- 6  next_day(..., 'friday') returns the next
 --    friday for a date which we need for the
 --    join:
 --
   on fridays.date_ = next_day(weeks.chrg_dt, 'friday')
 group by
   fridays.date_;

清理:

 drop table tq84_sum_data_by_week purge;

SQL Fiddle

上也是如此