使用两个日期列合并两个表并复制行

Posted

技术标签:

【中文标题】使用两个日期列合并两个表并复制行【英文标题】:Merge two tables and replicate rows using two date columns 【发布时间】:2020-04-16 11:49:05 【问题描述】:

我有这些表:

CREATE TABLE TABLE_4 
(
    DATE_INI    DATE NOT NULL,
    DATE_FIN    DATE NOT NULL,
    TOT_CLIENT  NUMBER NOT NULL,
    LOCATOR NUMBER NOT NULL
);

INSERT INTO TABLE_4 (DATE_INI, DATE_FIN, TOT_CLIENT, LOCATOR) 
VALUES (to_date('19/9/23', 'RR/MM/DD'), to_date('19/9/26', 'RR/MM/DD'), 3, 758908);
INSERT INTO TABLE_4 (DATE_INI, DATE_FIN, TOT_CLIENT, LOCATOR) 
VALUES (to_date('19/9/23', 'RR/MM/DD'), to_date('19/9/26', 'RR/MM/DD'), 2, 765590);

CREATE TABLE TABLE_5 
( 
    LOCATOR     NUMBER NOT NULL,
    DATE_CLIENT DATE NOT NULL,
    NAME        VARCHAR2(250) NOT NULL
);

INSERT INTO TABLE_5 (LOCATOR, DATE_CLIENT, NAME) 
VALUES (758908, to_date('19/9/23', 'RR/MM/DD'), 'Maria');
INSERT INTO TABLE_5 (LOCATOR, DATE_CLIENT, NAME) 
VALUES (758908, to_date('19/9/23', 'RR/MM/DD'), 'Luis');
INSERT INTO TABLE_5 (LOCATOR, DATE_CLIENT, NAME) 
VALUES (758908, to_date('19/9/23', 'RR/MM/DD'), 'Pedro');
INSERT INTO TABLE_5 (LOCATOR, DATE_CLIENT, NAME) 
VALUES (765590, to_date('19/9/23', 'RR/MM/DD'), 'Manuel');
INSERT INTO TABLE_5 (LOCATOR, DATE_CLIENT, NAME) 
VALUES (765590, to_date('19/9/23', 'RR/MM/DD'), 'Ana');

CREATE SEQUENCE SEQ_TABLE_6  
MINVALUE 1 MAXVALUE 9999999999999999999999999999 
INCREMENT BY 1 
START WITH 2206 
NOCACHE ORDER NOCYCLE NOKEEP NOSCALE GLOBAL;

CREATE TABLE TABLE_6 
(
     ID NUMBER DEFAULT SEQ_TABLE_6.nextval  NOT NULL,
     ACTUAL_DATE    DATE NOT NULL,
     DATE_INI       DATE NOT NULL,
     DATE_FIN       DATE NOT NULL,
     LOCATOR        NUMBER NOT NULL,
     NAME           VARCHAR2(250) NOT NULL
);

有可能得到这个结果吗?

想法是:

    根据 date_ini 和 date_fin 创建行,创建这些列之间的所有日期。正如您在 table_6 上的“actual_date”上看到的那样

    按日期行复制我们在 table_5 上的信息

有人可以帮我解决这个问题吗?

问候

【问题讨论】:

【参考方案1】:

您可以使用递归查询来做到这一点:

insert into table_6(actual_date, date_ini, date_fin, locator, name) 
with cte (actual_date, date_ini, date_fin, locator, name) as (
    select t4.date_ini actual_date, t4.date_ini, t4.date_fin, t5.locator, t5.name
    from table_4 t4
    inner join table_5 t5 on t5.date_client = t4.date_ini and t5.locator = t4.locator
    union all
    select actual_date + 1, date_ini, date_fin, locator, name
    from cte
    where actual_date < date_fin
)
select * from cte

Demo on DB Fiddle

身份证 | ACTUAL_DATE | DATE_INI | DATE_FIN |定位器 |姓名 ---: | :------------ | :-------- | :-------- | ------: | :----- 2206 | 23-SEP-19 | 23-SEP-19 | 26-SEP-19 | 758908 |玛丽亚 2207 | 23-SEP-19 | 23-SEP-19 | 26-SEP-19 | 758908 |路易斯 2208 | 23-SEP-19 | 23-SEP-19 | 26-SEP-19 | 758908 |佩德罗 2209 | 23-SEP-19 | 23-SEP-19 | 26-SEP-19 | 765590 |曼努埃尔 2210 | 23-SEP-19 | 23-SEP-19 | 26-SEP-19 | 765590 |安娜 2211 | 19 年 9 月 24 日 | 23-SEP-19 | 26-SEP-19 | 758908 |玛丽亚 2212 | 19 年 9 月 24 日 | 23-SEP-19 | 26-SEP-19 | 758908 |路易斯 2213 | 19 年 9 月 24 日 | 23-SEP-19 | 26-SEP-19 | 758908 |佩德罗 第2214章19 年 9 月 24 日 | 23-SEP-19 | 26-SEP-19 | 765590 |曼努埃尔 2215 | 19 年 9 月 24 日 | 23-SEP-19 | 26-SEP-19 | 765590 |安娜 2216 | 25-SEP-19 | 23-SEP-19 | 26-SEP-19 | 758908 |玛丽亚 2217 | 25-SEP-19 | 23-SEP-19 | 26-SEP-19 | 758908 |路易斯 2218 | 25-SEP-19 | 23-SEP-19 | 26-SEP-19 | 758908 |佩德罗 2219 | 25-SEP-19 | 23-SEP-19 | 26-SEP-19 | 765590 |曼努埃尔 2220 | 25-SEP-19 | 23-SEP-19 | 26-SEP-19 | 765590 |安娜 2221 | 26-SEP-19 | 23-SEP-19 | 26-SEP-19 | 758908 |玛丽亚 第2222章26-SEP-19 | 23-SEP-19 | 26-SEP-19 | 758908 |路易斯 第2223章26-SEP-19 | 23-SEP-19 | 26-SEP-19 | 758908 |佩德罗 第2224章26-SEP-19 | 23-SEP-19 | 26-SEP-19 | 765590 |曼努埃尔 2225 | 26-SEP-19 | 23-SEP-19 | 26-SEP-19 | 765590 |安娜

【讨论】:

【参考方案2】:

您可以对子查询分解进行同样的操作,如下所示

        WITH data
         AS (SELECT date_ini + column_value - 1 AS dates,
                    date_ini,
                    date_fin,
                    tot_client,
                    locator
             FROM   table_4
                    cross join TABLE(Cast(MULTISET (SELECT LEVEL
                                              FROM   dual
                                              CONNECT BY date_ini + LEVEL <=
                                                         date_fin + 1
                                                   )
                                          AS
         sys.ODCINUMBERLIST))),
         data1
         AS (SELECT dates,
                    date_ini,
                    date_fin,
                    locator
             FROM   data
             ORDER  BY dates,
                       date_ini,
                       date_fin,
                       locator)
    SELECT d1.*,
           t5.name
    FROM   data1 d1,
           table_5 t5
    WHERE  d1.locator = t5.locator 
    and d1.date_ini=t5.date_client

下面的输出

        DATES   DATE_INI    DATE_FIN    LOCATOR NAME
    23-SEP-19   23-SEP-19   26-SEP-19   758908  Pedro
    23-SEP-19   23-SEP-19   26-SEP-19   758908  Maria
    23-SEP-19   23-SEP-19   26-SEP-19   758908  Luis
    23-SEP-19   23-SEP-19   26-SEP-19   765590  Manuel
    23-SEP-19   23-SEP-19   26-SEP-19   765590  Ana
    24-SEP-19   23-SEP-19   26-SEP-19   758908  Pedro
    24-SEP-19   23-SEP-19   26-SEP-19   758908  Luis
    24-SEP-19   23-SEP-19   26-SEP-19   758908  Maria
    24-SEP-19   23-SEP-19   26-SEP-19   765590  Ana
    24-SEP-19   23-SEP-19   26-SEP-19   765590  Manuel
    25-SEP-19   23-SEP-19   26-SEP-19   758908  Maria
    25-SEP-19   23-SEP-19   26-SEP-19   758908  Luis
    25-SEP-19   23-SEP-19   26-SEP-19   758908  Pedro
    25-SEP-19   23-SEP-19   26-SEP-19   765590  Ana
    25-SEP-19   23-SEP-19   26-SEP-19   765590  Manuel
    26-SEP-19   23-SEP-19   26-SEP-19   758908  Maria
    26-SEP-19   23-SEP-19   26-SEP-19   758908  Luis
    26-SEP-19   23-SEP-19   26-SEP-19   758908  Pedro
    26-SEP-19   23-SEP-19   26-SEP-19   765590  Ana
    26-SEP-19   23-SEP-19   26-SEP-19   765590  Manuel

【讨论】:

以上是关于使用两个日期列合并两个表并复制行的主要内容,如果未能解决你的问题,请参考以下文章

如何在导入数据库期间合并两个 excel 列?

使用不同的时间间隔合并并填充Pandas中的两个数据帧

t-sql 合并两个表并替换空值

将具有两个日期列的一个数据框与另一个具有两个日期列的数据框合并

如何根据日期列合并两个数据框?

如何在 C# 中使用 csvHelper 将两个单独列中的日期和时间合并到一个新的日期时间列中