Вставить строки в существующую таблицу, которые охватывают диапазон, указанный в 2 столбцах - PullRequest
0 голосов
/ 02 апреля 2019

Я пытаюсь создать таблицу, которая отображает рекламные акции на основе идентификатора группы и еженедельно. У меня есть таблица, которая показывает для каждой группы ID, какое продвижение было и сколько недель оно длилось, включая дату начала и дату окончания.

Я хочу вставить номер недели в эту таблицу, чтобы, если продвижение длилось 2 недели, я видел идентификатор группы в двух отдельных строках с номерами двух недель в столбце рядом с ним и дубликат всей другой информации.

Я пытался работать с функцией модели, но не могу понять, как применить ее к моим данным.

Моя текущая таблица выглядит так:

GROUP_ID   PROMOTION_DESCRIPTION            START_DATE  END_DATE   WEEKS  START_YEARWEEK   END_YEARWEEK   MEDIA_SUPPORT
40284      Gehwol / Wartner 2e halve prijs  27-06-17    01-07-17   1      201726           201726         Radio
40315      Voordeelzakken En Dozen          26-06-17    09-07-17   2      201726           201727         Online Campagne

И я хочу, чтобы это выглядело так:

GROUP_ID   WEEK     PROMOTION_DESCRIPTION              MEDIA_SUPPORT
40284      201706   Gehwol / Wartner 2e halve prijs    Radio
40315      201726   Voordeelzakken En Dozen            Online Campagne
40315      201727   Voordeelzakken En Dozen            Online Campagne

Любая помощь будет принята с благодарностью!

Ответы [ 3 ]

0 голосов
/ 02 апреля 2019

Этот рекурсивный запрос может сделать это:

with c(rn, group_id, week, weeks, promotion_description, media_support) as (
  select 1, group_id, start_yearweek, weeks, promotion_description, media_support from t 
  union all
  select rn + 1, group_id, week + 1, weeks, promotion_description, media_support 
    from c where rn < weeks)
select group_id, week, weeks, promotion_description, media_support from c 

демо

0 голосов
/ 02 апреля 2019

Вы можете использовать такую ​​комбинацию стиля connect by level ниже, чтобы получить больше строк в зависимости от ваших данных и ограничить их до определенной суммы, управляя ключевым словом distinct.

with t( group_id, promotion_description, start_yearweek, end_yearweek, media_support ) as
(
 select 40284, 'Gehwol / Wartner 2e halve prijs', 201726, 201726, 'Radio' from dual union all
 select 40315, 'Voordeelzakken En Dozen', 201726, 201727, 'Online Campagne' from dual 
), t1 as
(
  select group_id,  
         sum(end_yearweek - start_yearweek + 1 ) as weeks
    from t
   group by group_id    
  )
  select distinct t1.group_id, start_yearweek + level - 1 as week,
         promotion_description, media_support 
   from t1
   join t on t1.group_id = t.group_id   
 connect by level <= weeks
  order by group_id, week;

 GROUP_ID   WEEK    PROMOTION_DESCRIPTION            MEDIA_SUPPORT
 --------   ------  -------------------------------  ---------------
 40284      201726  Gehwol / Wartner 2e halve prijs  Radio
 40315      201726  Voordeelzakken En Dozen          Online Campagne
 40315      201727  Voordeelzakken En Dozen          Online Campagne

P.S. Нет необходимости хранить столбец weeks, который можно рассчитать с помощью запроса.

Демо

0 голосов
/ 02 апреля 2019

Это можно сделать, создав календарь и добавив его к данным рекламной акции.

В приведенном ниже примере создается субфактор calendar, который включает одну запись для каждой недели (включая неделю 53) для 2017, 2018, 2019 годов, а затем объединяет любую запись promotion, чьи start_yearweek и end_yearweek пересекаются с этим календарная неделя.

WITH CALENDAR AS (
    SELECT (100 * YEAR_OFFSET) + WEEK_OFFSET AS CALENDAR_WEEK
    FROM (
        SELECT LEVEL AS WEEK_OFFSET
        FROM DUAL
        CONNECT BY LEVEL <= 53)
             CROSS JOIN (SELECT 2016 + LEVEL AS YEAR_OFFSET
                         FROM DUAL
                         CONNECT BY LEVEL <= 3))
SELECT GROUP_ID,
    CALENDAR_WEEK,
    PROMOTION_DESCRIPTION,
    MEDIA_SUPPORT
FROM CALENDAR
         INNER JOIN PROMOTION
ON CALENDAR_WEEK
    BETWEEN START_YEARWEEK AND END_YEAR_WEEK;

Результат:

  GROUP_ID   CALENDAR_WEEK PROMOTION_DESCRIPTION             MEDIA_SUPPORT
     40284          201726 Gehwol / Wartner 2e halve prijs   Radio
     40315          201726 Voordeelzakken En Dozen           Online Campagne
     40315          201727 Voordeelzakken En Dozen           Online Campagne


3 rows selected.

РЕДАКТИРОВАТЬ: Для создания календаря ISO-недели можно использовать маску формата «IW» в TO_DATE.

Этот пример календаря генерирует недели ISO с 2014 по 2022 год:

SELECT DISTINCT TO_NUMBER(TO_CHAR((DATE '2014-01-01' + LEVEL),'YYYYIW'))
    AS ISO_CALENDAR_WEEK FROM DUAL 
CONNECT BY (DATE '2014-01-01' + LEVEL) < DATE '2023-01-01';

В примере продвижения это можно использовать как:

WITH CALENDAR AS (
    SELECT DISTINCT TO_NUMBER(TO_CHAR((DATE '2014-01-01' + LEVEL),'YYYYIW'))
        AS ISO_CALENDAR_WEEK FROM DUAL
    CONNECT BY (DATE '2014-01-01' + LEVEL) < DATE '2023-01-01' )
SELECT GROUP_ID,
    ISO_CALENDAR_WEEK,
    PROMOTION_DESCRIPTION,
    MEDIA_SUPPORT
FROM CALENDAR
         INNER JOIN PROMOTION
ON ISO_CALENDAR_WEEK
    BETWEEN START_YEARWEEK AND END_YEAR_WEEK;

Результат:

  GROUP_ID   ISO_CALENDAR_WEEK PROMOTION_DESCRIPTION             MEDIA_SUPPORT
     40315              201727 Voordeelzakken En Dozen           Online Campagne
     40284              201726 Gehwol / Wartner 2e halve prijs   Radio
     40315              201726 Voordeelzakken En Dozen           Online Campagne


3 rows selected.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...