在甲骨文每周分组

时间:2018-10-12 06:04:14

标签: sql oracle group-by

我需要每周从oracle SQL进行分组,我有下表包含数量,该表分为几个类别。我需要获取每个类别的每周数量总和。

源表:quantity_details

date (mm/dd/yyyy)   quantity    category
10/1/2018             4            A
10/2/2018             4            B
10/3/2018             5            C
10/4/2018             7            A
10/5/2018             2            A
10/6/2018             2            B
10/7/2018             1            C
10/8/2018             0            C
10/9/2018             8            C
10/10/2018            2            B
10/11/2018            4            D
10/12/2018            6            B
10/13/2018            8            D
10/14/2018            9            C
10/15/2018            11           A

结果表应如下所示:

week start date (dd/mm/yyyy)    category    sum of quantity
01/10/2018 to 07/10/2018            A            13
01/10/2018 to 07/10/2018            B             6
01/10/2018 to 07/10/2018            C             6
01/10/2018 to 07/10/2018            D             0
08/10/2018 to 14/10/2018            A             0
08/10/2018 to 14/10/2018            B             8
08/10/2018 to 14/10/2018            C            17
08/10/2018 to 14/10/2018            D            12
15/10/2018 to 21/10/2018            A            11
15/10/2018 to 21/10/2018            B             0
15/10/2018 to 21/10/2018            C             0
15/10/2018 to 21/10/2018            D             0

2 个答案:

答案 0 :(得分:1)

您可以使用:

select to_char(trunc(min(min_Date),'iw'),'dd/mm/yyyy')||' to '
     ||to_char(trunc(min(min_Date),'iw')+6,'dd/mm/yyyy') as week,
    as week,
       category, sum(sum_of_quantity) as sum_of_quantity
  from
(
  select to_char(myDate,'iw') as week, min(myDate) as min_Date, max(myDate) max_Date, 
         category, sum(quantity) as sum_of_quantity
    from quantity_details
   group by to_char(myDate,'iw'), category
) 
group by week, category
order by week, category;

WEEK                     CATEGORY  SUM_OF_QUANTITY
------------------------ --------  ---------------
01/10/2018 to 07/10/2018    A            13
01/10/2018 to 07/10/2018    B             6
01/10/2018 to 07/10/2018    C             6
08/10/2018 to 14/10/2018    B             8
08/10/2018 to 14/10/2018    C            17
08/10/2018 to 14/10/2018    D            12
15/10/2018 to 21/10/2018    A            11

SQL Fiddle Demo 1

如果您想将所有类别及其数量都包含为zero,即使它们不匹配,我们也应该更加努力地将left join的贡献作为:

select to_char(trunc(q1.min_Date,'iw'),'dd/mm/yyyy')||' to '
     ||to_char(trunc(q1.min_Date,'iw')+6,'dd/mm/yyyy') as week,
       q1.category,
       nvl(q2.quantity,0) as sum_of_quantity
  from
( 
  select to_char(d1.myDate,'iw') as week, min(d1.myDate) as min_Date,
         max(d1.myDate) max_Date, d2.category
    from quantity_details d1 
   cross join ( select category from quantity_details group by category ) d2
   group by to_char(d1.myDate,'iw'), d2.category
) q1
 left join
(
  select to_char(myDate,'iw') as week, min(myDate) as min_Date, max(myDate) max_Date, 
         category, sum(quantity) as quantity
    from quantity_details
   group by to_char(myDate,'iw'), category
) q2 on ( q1.category = q2.category and q1.week = q2.week )
 order by q1.week, q1.category;

WEEK                     CATEGORY  SUM_OF_QUANTITY
------------------------ --------  ---------------
01/10/2018 to 07/10/2018    A            13
01/10/2018 to 07/10/2018    B             6
01/10/2018 to 07/10/2018    C             6
01/10/2018 to 07/10/2018    D             0
08/10/2018 to 14/10/2018    A             0
08/10/2018 to 14/10/2018    B             8
08/10/2018 to 14/10/2018    C            17
08/10/2018 to 14/10/2018    D            12
15/10/2018 to 21/10/2018    A            11
15/10/2018 to 21/10/2018    B             0
15/10/2018 to 21/10/2018    C             0
15/10/2018 to 21/10/2018    D             0

SQL Fiddle Demo Main

答案 1 :(得分:0)

由于您似乎需要结果集中的“零”,因此这些想法​​可能会有所帮助:{1}找到所有可能的(唯一)WEEK x CATEGORY组合(下面查询中的子查询C){2}找到每周的总和(以下查询中的子查询S。{3}左联接2,这样对于没有总和的周,您将获得NULL值。{4}选择所需的列,并替换空值(使用Oracle 11和12进行测试,请参见dbfiddle

select 
  to_char( C.startofweek, 'DD/MM/YYYY' ) || ' to ' 
  || to_char( C.startofweek + 6, 'DD/MM/YYYY'  ) as "week from/to"
, C.category
, case 
    when S.sumofweek is null then 0
    else S.sumofweek
  end as "sum of quantity"  
from ( 
  select unique 
    startofweek, category
  from 
    ( select unique trunc( date_, 'w') startofweek from test_ )
  , ( select unique category from test_ ) 
) C left join (
  select unique
    category
  , trunc( date_, 'w') startofweek
  , sum( quantity ) over ( partition by category, trunc( date_, 'w') ) sumofweek
  from test_ 
) S 
  on C.startofweek = S.startofweek and C.category = S.category
order by C.startofweek, C.category 
;

结果

week from/to              CATEGORY  sum of quantity
01/10/2018 to 07/10/2018  A         13
01/10/2018 to 07/10/2018  B         6
01/10/2018 to 07/10/2018  C         6
01/10/2018 to 07/10/2018  D         0
08/10/2018 to 14/10/2018  A         0
08/10/2018 to 14/10/2018  B         8
08/10/2018 to 14/10/2018  C         17
08/10/2018 to 14/10/2018  D         12
15/10/2018 to 21/10/2018  A         11
15/10/2018 to 21/10/2018  B         0
15/10/2018 to 21/10/2018  C         0
15/10/2018 to 21/10/2018  D         0