首页 > 解决方案 > 将行插入到现有表中,该表跨越 2 列中指定的范围

问题描述

我正在尝试创建一个表格,以组 ID 和每周为单位显示促销活动。我有一个表格,显示每个组 ID 有什么促销活动以及持续了多少周,包括开始日期和结束日期。

我想在此表中插入周数,以便如果促销持续 2 周,我会在两个单独的行中看到组 ID,其旁边的列中包含两个周数,以及所有其他信息的副本。

我曾尝试使用模型函数,但似乎无法弄清楚如何将其应用于我的数据。

我当前的表格如下所示:

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

任何帮助将不胜感激!

标签: sqloracle

解决方案


这可以通过生成日历并将其加入促销数据来完成。

下面的示例创建一个calendar子因子,其中包括 2017 年、2018 年、2019 年的每周(包括第 53 周)的一条记录,然后加入与该日历周相交的任何promotion记录。start_yearweekend_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 周日历,可以在TO_DATE.

此示例日历生成从 2014 年到 2022 年的 ISO 周:

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.

推荐阅读