我在oracle数据库中有一个表,其数据如下所示
G_DATE P_KEY P_STATUS P_USER P_CD
3/1/2019 1 old a bb
3/1/2019 2 old b ab
3/1/2019 3 new c cb
3/1/2019 4 med c cb
3/2/2019 1 old a bb
3/2/2019 2 old b ab
3/2/2019 3 new c cb
3/2/2019 4 med c cb
3/3/2019 1 old a bb
3/3/2019 2 new d ab
3/3/2019 3 med d cb
3/3/2019 4 new c cb
3/4/2019 1 med d bb
3/4/2019 2 old d xy
3/4/2019 3 med d cb
3/4/2019 5 new c cb
3/5/2019 1 old a bb
3/5/2019 2 new d ab
3/5/2019 3 med d cb
3/5/2019 5 new c xy
并且我正在尝试使用解析函数来提供代码以选择以下数据,但是我正在努力比较这些组合。
这就像我们正在构造一个尺寸变化缓慢的维度表一样,只要这3个属性中的任何一个发生变化,填充的有效日期和结束日期就会被填充。 p_STATUS,p_cD,P_UsER 自然键是g_date和p_key。如果您注意到我发布的输出,对于给定的p_key和g_date,我们必须跟踪属性的任何更改。
上表中的主键是p_key和g_date,对于p_status,p_user和p_cd的每个更改,都需要选择一个新行,并为eff_dt和end_dt进行相应的更改,分别用于g_date和p_key的每个组合。能否请您提供一些有关如何实现低于输出的建议
P_KEY P_STATUS P_USER P_CD eff_dt end_dt latest_row_flag
1 old a bb 3/1/2019 3/3/2019 N
1 med d bb 3/4/2019 3/4/2019 N
1 old a bb 3/5/2019 12/31/4712 Y
2 old b ab 3/1/2019 3/2/2019 N
2 new d ab 3/3/2019 3/3/2019 N
2 old d xy 3/4/2019 3/5/2019 N
2 new d ab 3/5/2019 12/31/4712 Y
3 new c cb 3/1/2019 3/2/2019 N
3 med d cb 3/3/2019 12/31/4712 Y
4 med c cb 3/1/2019 3/2/2019 N
4 new c cb 3/3/2019 12/31/4712 Y
5 new c cb 3/4/2019 3/4/2019 N
5 new c xy 3/5/2019 12/31/4712 Y
----用于创建表并将行插入表的脚本
create table work_audit
( g_date date,
P_key number,
P_status varchar2(10),
p_user varchar2(10),
p_cd varchar2(10)
);
SET DEFINE OFF;
Insert into WORK_AUDIT
(G_DATE, P_KEY, P_STATUS, P_USER, P_CD)
Values
(TO_DATE('3/1/2019', 'MM/DD/YYYY'), 1, 'old', 'a', 'bb');
Insert into WORK_AUDIT
(G_DATE, P_KEY, P_STATUS, P_USER, P_CD)
Values
(TO_DATE('3/1/2019', 'MM/DD/YYYY'), 3, 'new', 'c', 'cb');
Insert into WORK_AUDIT
(G_DATE, P_KEY, P_STATUS, P_USER, P_CD)
Values
(TO_DATE('3/1/2019', 'MM/DD/YYYY'), 4, 'med', 'c', 'cb');
Insert into WORK_AUDIT
(G_DATE, P_KEY, P_STATUS, P_USER, P_CD)
Values
(TO_DATE('3/1/2019', 'MM/DD/YYYY'), 2, 'old', 'b', 'ab');
Insert into WORK_AUDIT
(G_DATE, P_KEY, P_STATUS, P_USER, P_CD)
Values
(TO_DATE('3/2/2019', 'MM/DD/YYYY'), 3, 'new', 'c', 'cb');
Insert into WORK_AUDIT
(G_DATE, P_KEY, P_STATUS, P_USER, P_CD)
Values
(TO_DATE('3/2/2019', 'MM/DD/YYYY'), 1, 'old', 'a', 'bb');
Insert into WORK_AUDIT
(G_DATE, P_KEY, P_STATUS, P_USER, P_CD)
Values
(TO_DATE('3/2/2019', 'MM/DD/YYYY'), 2, 'old', 'b', 'ab');
Insert into WORK_AUDIT
(G_DATE, P_KEY, P_STATUS, P_USER, P_CD)
Values
(TO_DATE('3/2/2019', 'MM/DD/YYYY'), 4, 'med', 'c', 'cb');
Insert into WORK_AUDIT
(G_DATE, P_KEY, P_STATUS, P_USER, P_CD)
Values
(TO_DATE('3/3/2019', 'MM/DD/YYYY'), 1, 'old', 'a', 'bb');
Insert into WORK_AUDIT
(G_DATE, P_KEY, P_STATUS, P_USER, P_CD)
Values
(TO_DATE('3/3/2019', 'MM/DD/YYYY'), 2, 'new', 'd', 'ab');
Insert into WORK_AUDIT
(G_DATE, P_KEY, P_STATUS, P_USER, P_CD)
Values
(TO_DATE('3/3/2019', 'MM/DD/YYYY'), 3, 'med', 'd', 'cb');
Insert into WORK_AUDIT
(G_DATE, P_KEY, P_STATUS, P_USER, P_CD)
Values
(TO_DATE('3/3/2019', 'MM/DD/YYYY'), 4, 'new', 'c', 'cb');
Insert into WORK_AUDIT
(G_DATE, P_KEY, P_STATUS, P_USER, P_CD)
Values
(TO_DATE('3/4/2019', 'MM/DD/YYYY'), 1, 'med', 'd', 'bb');
Insert into WORK_AUDIT
(G_DATE, P_KEY, P_STATUS, P_USER, P_CD)
Values
(TO_DATE('3/4/2019', 'MM/DD/YYYY'), 2, 'old', 'd', 'xy');
Insert into WORK_AUDIT
(G_DATE, P_KEY, P_STATUS, P_USER, P_CD)
Values
(TO_DATE('3/4/2019', 'MM/DD/YYYY'), 3, 'med', 'd', 'cb');
Insert into WORK_AUDIT
(G_DATE, P_KEY, P_STATUS, P_USER, P_CD)
Values
(TO_DATE('3/4/2019', 'MM/DD/YYYY'), 5, 'new', 'c', 'cb');
COMMIT;
答案 0 :(得分:1)
如果我理解正确,这是一个空白与孤岛的问题。
这应该做您想要的:
select p_key, p_status, p_user, p_cd, min(g_date) as start_dt,
(case when max_g_date = max(g_date) then date '4712-12-31' else max(g_date) end) as end_dt,
(case when max_g_date = max(g_date) then 1 else 0 end) as latest_row_flag
from (select wa.*,
row_number() over (partition by p_key order by g_date) as seqnum,
row_number() over (partition by p_key, p_status, p_user, p_cd order by g_date) as seqnum_2,
max(g_date) over () as max_g_date
from work_audit wa
) wa
group by p_key, p_status, p_user, p_cd, (seqnum - seqnum_2), max_g_date
order by p_key, min(g_date);
Here是db <>小提琴。小提琴使用Postgres,因为Oracle在db <> fiddle上不能很好地工作。但是查询不会改变。