【发布时间】:2017-02-01 16:48:07
【问题描述】:
考虑一个可以随时间跟踪最喜欢的颜色的表格。
drop table favourites;
create table favourites(
person_id varchar2(10) not null
,valid_from date not null
,valid_to date
,color varchar2(10) not null
,constraint favourites_pk primary key(person_id, valid_from)
);
insert into favourites values('Ronnie', date '1979-09-12', null, 'Green');
insert into favourites values('Ronnie', date '2000-01-01', date '2016-12-31', 'Blue');
commit;
表格显示“Ronnie”从 1979 年 9 月 12 日开始喜欢绿色,然后从 2000 年 1 月 1 日开始他喜欢蓝色。当罗尼在 2017 年的第一天醒来时,他不再喜欢 Blue。
我需要使用一次性脚本清理表格,但我遇到了上面显示的特定情况。到目前为止,最好的想法是根据 valid_from 日期重新计算 valid_to 日期,但在这种情况下,我实际上破坏了信息:如下所示,“绿色”不再是 2017-01-01 的最爱,它应该是。
select person_id
,valid_from
,valid_to
,lead(valid_from,1) over(partition by person_id order by valid_from)-1 as valid_to2
,color
from favourites t;
PERSON_ID VALID_FROM VALID_TO NEW_VALID_TO COLOR
--------- ---------- ---------- ------------ ------
Ronnie 1979-09-12 null 1999-12-31 Green
Ronnie 2000-01-01 2016-12-31 null Blue
如何生成附加记录,以便最终结果为:
PERSON_ID VALID_FROM VALID_TO COLOR
--------- ---------- ---------- ------
Ronnie 1979-09-12 1999-12-31 Green
Ronnie 2000-01-01 2016-12-31 Blue
Ronnie 2017-01-01 null Green
编辑
valid_to 日期背后没有合理的逻辑。这是用户投入的内容,因此存在各种疯狂的重叠。 null 表示“永远”,或者 9999-12-31,如果它更容易理解的话。我想通过创建另一个表来修复这个设计,但首先我需要一种方法来修复旧数据。
也许这样看更容易。
Green |---------------------------------->
Blue |------|
我通过计算一个新的valid_to日期来修复重叠,我销毁了信息:
Green |--------|
Blue |------|
它必须像这样修复:
Green |--------|
Blue |------|
Green |-------->
原始数据集中的问题仅在第二个查询中出现(由于重叠)。其他两个显示正确的结果。
select *
from favourites
where (date '1995-01-01' >= valid_from)
and (date '1995-01-01' <= valid_to or valid_to is null);
select *
from favourites
where (date '2015-01-01' >= valid_from)
and (date '2015-01-01' <= valid_to or valid_to is null);
select *
from favourites
where (date '2025-01-01' >= valid_from)
and (date '2025-01-01' <= valid_to or valid_to is null);
【问题讨论】:
-
这是唯一的重叠示例吗?
-
为什么新插入的行的颜色应该是绿色的?可以为空吗?
-
你怎么知道他在 2017 年又开始喜欢绿色了?某处有默认规则吗?
-
vkp 在上述评论中的建议是最有意义的。表格中的数据告诉您,Ronnie 喜欢 Blue 到 2016 年底。如果您没有其他信息,那么从那时起他喜欢什么就不得而知了,
null正是为此。我们怎么知道他不再喜欢蓝色,更不用说绿色或蓝色以外的颜色了? (或者您是否有其他未分享的条件,例如喜欢的颜色不可为空,只有两个可能的值,并且颜色必须从一行到下一行交替出现?) -
@GordonLinoff,不,还有更多类型的重叠,但我已经解决了。