我有一个表,它看起来像这样(不要介意数据库供应商,因为我在ANSI SQL中需要它):
create table edge (
parent_id int not null,
child_id int not null,
value float not null,
start date not null,
end date not null
)
字符串
然后,我将获得以下CSV输入数据:
1,2,0,2023-01-01,2023-01-10
1,2,0,2023-01-11,2023-01-20
1,2,0,2023-01-21,NULL
1,3,0,2023-01-01,2023-01-10
1,3,0,2023-01-11,2023-01-20
1,3,1,2023-01-21,NULL
型
请注意,如果父级为1,子级为2,则相同的值0在多个日期间隔中重复,因此它可以折叠为:
1,2,0,2023-01-01,NULL
1,3,0,2023-01-01,2023-01-20
1,3,1,2023-01-21,NULL
型end
中的值NULL
表示有效,直到另行通知。
理想情况下,应该有一个查询,它会为表边缘(是的,图边缘)生成第二个摘录的输出。目标是首先删除冗余行,并使用start
更新剩余的最后一行,以匹配第一个删除行的start
。
我能得到的最接近的是下面的,在这里我找到了所有要删除的冗余行:
SELECT *
FROM edge
WHERE (parent, child, value, start) IN (SELECT parent, child, value, end+1
FROM edge)
ORDER BY parent, child, start
型
然后我需要做更新步骤来保持时间序列的一致性。另外,value
是完全匹配的,它是一个浮点数,但这至少在PostgreSQL上有效。
如果没有办法使用ANSI,我会有兴趣学习PostgreSQL的情况。
2条答案
按热度按时间ukdjmx9f1#
我首先建议使用一个查询,根据上面的业务规则选择所需的行,可以使用(作为视图?)而不删除。我使用的是非ANSI
distinct on
PostgreSQL的子句。字符串
如果这是不可接受的,则将查询整形为CTE,然后删除不在其中的这些行。
下面是一个符合SQL标准的版本w/o
distinct on
。型
SQL Fiddle demo
svujldwt2#
如果日期范围是连续的,我认为最简单的(但有点脏)方法如下:
1.将
end
设置为未来的唯一日期,其中为null
。1.将值放入新边表:
字符串
1.将
end
设置为null
,它与之前设置的唯一日期匹配,并删除旧表。