使用两个日期列合并两个表并复制行
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
【讨论】:
以上是关于使用两个日期列合并两个表并复制行的主要内容,如果未能解决你的问题,请参考以下文章