我有一个表
ab_relationship
描述了 A 和 B 之间的关系以及该关系的结束日期,或者如果该关系仍然有效,则在 NULL
列中显示 end
。在对该数据库进行手动查询时,通常希望找到在给定时间哪个关系有效。
因此,我正在寻找添加另一列“开始”的最佳方法,其中包含开始日期,如果它是给定 A 的第一个条目,则为 NULL,或者给定 A 的最后一个条目的结束日期。
要明确的是,我不想永久更改表
ab_relationship
我想创建一个临时视图或表以在后续查询中使用。
旧桌子
a_id b_id end
---- ---- ---
1 10 2000-01-01
2 10 2000-06-01
1 30 2010-01-01
3 20 NULL
2 20 NULL
1 10 NULL
期望的结果:
a_id b_id start end
---- ---- ----- ---
1 10 NULL 2000-01-01
2 10 NULL 2000-06-01
1 30 2000-01-01 2010-01-01
3 20 NULL NULL
2 20 2000-06-01 NULL
1 10 2010-01-01 NULL
如果将末尾列中的 NULL 值替换为类似
9999-12-31
的值就可以了
理想情况下,该解决方案应该同时适用于 SQLite 和 SQL Server。
为什么要添加起始栏?
当我按原样使用该表并将其与包含感兴趣日期的其他表连接时,显然我会为每个给定的 A 获得多行。通过简单的方法可以轻松过滤结束日期小于所需时间点的行WHERE 语句。但为了找到剩余的最小结束日期,我目前需要对具有数百万行的连接表进行子查询。
有了开始日期,可以将过滤减少到两个简单的 where 语句。
还有其他列可以对行进行排序吗?如果没有,那么我认为下面的一个对于 sql server 来说是一个不错的选择:
查询:
with cte as
(
select a_id,b_id,[end],row_number()over(order by (select 1)) rn from ab_relationship
)
select a_id,b_id,lag([end])over (partition by a_id order by rn) [start],[end] from cte
order by rn
输出:
a_id | b_id | 开始 | 结束 |
---|---|---|---|
1 | 10 | 空 | 2000-01-01 |
2 | 10 | 空 | 2000-06-01 |
1 | 30 | 2000-01-01 | 2010-01-01 |
3 | 20 | 空 | 空 |
2 | 20 | 2000-06-01 | 空 |
1 | 10 | 2010-01-01 | 空 |