SQL: суммируйте данные каждые 14 дней в течение всего года - PullRequest
1 голос
/ 01 мая 2011

EMP__ID | Work_Date | Items_sold

1         1/1/2010       10

2         1/1/2010        5

1         2/1/2010        7

1         3/1/2010       13

2         4/1/2010        6

Я хочу написать запрос, который будет sum "Items_Sold" каждые 14 дней (две недели) за весь год 2010

, чтобы было более понятно, этот запрос должен вернуть ( 26 строк ), что является числом раз в год , в каждом ряду будет всего Items_Sold, которые были захвачены именно в этом fortnight

Я использую SQL Navigator (оракул)SQL)

большое спасибо за помощь

наилучшие пожелания ,,

Ответы [ 4 ]

2 голосов
/ 01 мая 2011

Один из подходов - получить неделю от деления даты на 2, добавить .1 и затем округлить ее. Это нормализует значения от 52 до 26. Одна проблема состоит в том, что есть 53 недели, поэтому вам следует проверить, когда это произойдет.

SELECT Round(Cast(To_char(work_date, 'WW') AS DEC(12, 2)) / 2 + .1) fortnight, 
       SUM(items_sold)  AS total_sold 
FROM   table1 
GROUP  BY Round(Cast(To_char(work_date, 'WW') AS DEC(12, 2)) / 2 + .1) 

Примечание: я не нахожусь рядом с коробкой Oracle, поэтому я не проверял это

1 голос
/ 01 мая 2011

Этот запрос возвращает 26 строк, которые выглядят следующим образом.

FORT_START  FORT_END        JULIAN_DATE     SUM(ITEMS_SOLD)
--
01-JAN-10   14-JAN-10       14              15
15-JAN-10   28-JAN-10       28              -
29-JAN-10   11-FEB-10       42              7
12-FEB-10   25-FEB-10       56              -
26-FEB-10   11-MAR-10       70              13
12-MAR-10   25-MAR-10       84              -
26-MAR-10   08-APR-10       98              6
09-APR-10   22-APR-10       112             -
...

Он создает календарь - просто таблицу дат - на 2010 год. На самом деле вы не можете получить все 26 строк, не имея 26 строк для объединения.

with calendar as (
select cal_date
from
(
  select to_date('01 2010','MM YYYY')-1 + level as cal_date
  from dual
  where (to_date('01 2010','MM YYYY')-1+level) <= last_day(to_date('12 2010','MM YYYY'))
  connect by level<=365
)
order by cal_date
)
select cal_date - 13 as fort_start, cal_date as fort_end, 
       to_number(to_char(cal_date, 'DDD')) as julian_date, sum(items_sold)
from calendar
left join table1 on (work_date between cal_date - 13 and cal_date)
where (cal_date between date '2010-01-01' and date '2010-12-31'
       and mod(to_number(to_char(cal_date, 'DDD')), 14) = 0
      ) 
group by cal_date - 13, cal_date, to_number(to_char(cal_date, 'DDD'))
order by cal_date;
0 голосов
/ 02 мая 2011

Это должно дать вам ровно 26 строк, начиная с 1 января с 14-дневными приращениями.Этого достаточно, чтобы начать?

select to_date('01-01-2010', 'DD-MM-YYYY') + (level-1)*14
from dual
connect by level <= 26;
0 голосов
/ 01 мая 2011

Я думаю, что это должно сделать

SELECT SUM(Items_sold) as num_sold
     , DATE_FORMAT(Emp_Date, '%Y') AS work_year
     , FLOOR((DATE_FORMAT(Work_Date, '%j') + 14) / 14) AS work_fortnight
  FROM thetable AS T 
 GROUP 
    BY DATE_FORMAT(Work_Date, '%Y'), FLOOR((DATE_FORMAT(Work_Date, '%j') + 14) / 14);

Впрочем, вероятно, это будет канун Нового года. Думаю, вы могли бы легко объяснить это вручную, если это необходимо. Я просто предположу, что этот магазин еще не открыт :)

...