如何在 sqlite 中查找剩余日期范围

问题描述 投票:0回答:1

我有一个类似sqlite的数据库

ID 从日期到日期

1 2023-04-02 2023-04-07

2 2023-04-05 2023-04-06

3 2023-04-09 2023-04-11

2 2023-04-09 2023-04-16

来自诱惑。

现在我正在获取堆栈以在 sqlite

中创建查询

当我搜索日期从 2023-04-02 到到 2023-04-30 时,每个 ID 的剩余日期范围应该填充。

预期产出

ID 从日期到日期

1 2023-04-08 2023-04-30

2 2023-04-02 2023-04-04

2 2023-04-07 2023-04-08

2 2023-04-17 2023-04-30

3 2023-04-02 2023-04-08

3 2023-04-12 2023-04-30

请帮助我

我尝试了很多东西但都失败了

sql sqlite recursive-query date-range
1个回答
0
投票

对于每个 ID,您想要在要求的期间内原始间隔集未涵盖的天数间隔。

前提是您的原始间隔不在同一 ID 内重叠。求左、右区间和并集

with tbl(ID, Fromdate, Todate) as (
  -- sample data
  select 1, julianday('2023-04-02'), julianday('2023-04-07') union all
  select 2, julianday('2023-04-05'), julianday('2023-04-06') union all
  select 3, julianday('2023-04-09'), julianday('2023-04-11') union all
  select 2, julianday('2023-04-09'), julianday('2023-04-16') 
),
params (ds, de) as (
  -- period to search within
  select julianday('2023-04-02'), julianday('2023-04-30')
), 
leftintvls as (
  -- the closest end of intervals relative to current interval start
  select id,  
    (select max(t2.Todate)+1  
     from tbl t2 
     where t2.id = t.id and t2.Todate < t.Fromdate ) ms, Fromdate-1 me
  from tbl t
  -- only itervals overlapping with the requierd period
  join params p on t.Fromdate <= p.de and p.ds <= t.Todate 
    --  starting later than required period starts
    and t.Fromdate > p.ds
),
rightintvls as (
  -- the closest start of interval relative current interval end
  select id, Todate+1 ms,  
    (select min(t2.Fromdate) - 1  
     from tbl t2 
     where t2.id = t.id and t2.Fromdate > t.Todate ) me
  from tbl t
  -- only itervals overlapping with the requierd period
  join params p on t.Fromdate <= p.de and p.ds <= t.Todate 
     --  ending earlier than required period ends
     and t.Todate < p.de  
)
select id, date(ifnull(ms, p.ds)) fromd, date(me) tod
from leftintvls
cross join params p
where ifnull(ms, p.ds) <= me  
  
union 
  
select id, date(ms),  date(ifnull(me, p.de))
from rightintvls
cross join params p
where ms <= ifnull(me, p.de)
order by id, fromd

db<>小提琴

© www.soinside.com 2019 - 2024. All rights reserved.