Oracle SQL问题:如何根据一张日期表创建时间段

huangapple go评论65阅读模式
英文:

Oracle SQL question: How to create periods based on a table of days

问题

2023-02-01 - 2023-02-03
2023-02-05 - 2023-02-09
2023-02-12 - 2023-02-28

英文:

I have a table Calendar that contains days.
If, as an example, the Calendar contains all days in the period 2023-02-01 to 2023-02-28 except the days 4, 10 and 11.

I would like to write a SQL that returns the three periods without the missing days like:<br/>
2023-02-01 - 2023-02-03<br/>
2023-02-05 - 2023-02-09<br/>
2023-02-12 - 2023-02-28

I write in the title that it is an Oracle question since I guess it is necessary to use analytical functions, but I cannot find out how.

Can anyone help me with that?

答案1

得分: 1

你可以尝试使用以下代码来获取实际间隔:

with dates as (select trunc(sysdate,'yy')+level sd from dual connect by level<10
union all
select trunc(sysdate,'yy')+level+13 sd from dual connect by level<5
union all
select trunc(sysdate,'yy')+level+25 sd from dual connect by level<3
)
select *
from (select sd, lag(sd) over (order by sd) lg
from dates) match_recognize(
order by sd
measures first(sd) as start_sd, last(sd)+1 as end_sd
one row per match
pattern (e+)
define e as sd=next(sd)-1);

结果如下:

02/01/2023 00:00:00	10/01/2023 00:00:00
15/01/2023 00:00:00	18/01/2023 00:00:00
27/01/2023 00:00:00	28/01/2023 00:00:00
英文:

You can try this to get the actual intervals

with dates as (select trunc(sysdate,&#39;yy&#39;)+level sd from dual connect by level&lt;10
union all
select trunc(sysdate,&#39;yy&#39;)+level+13 sd from dual connect by level&lt;5
union all
select trunc(sysdate,&#39;yy&#39;)+level+25 sd from dual connect by level&lt;3
)
select *
from (select sd, lag(sd) over (order by sd) lg
from dates) match_recognize(
order by sd
measures first(sd) as start_sd, last(sd)+1 as end_sd
one row per match
pattern (e+)
define e as sd=next(sd)-1);

02/01/2023 00:00:00	10/01/2023 00:00:00
15/01/2023 00:00:00	18/01/2023 00:00:00
27/01/2023 00:00:00	28/01/2023 00:00:00

答案2

得分: 0

我认为这应该有助于您获得您的结果

SELECT 
    prev_day, date_col 
FROM (
    SELECT 
        date_col 
        , LAG(date_col) OVER(ORDER BY date_col) prev_day
    FROM 
        Calendar 
    WHERE 
        date_col BETWEEN sysdate - 6 AND sysdate -- 指定期间
) WHERE date_col - prev_day &gt; 1
英文:

I think this should help you to got your result

SELECT 
    prev_day, date_col 
FROM (
    SELECT 
        date_col 
        , LAG(date_col) OVER(ORDER BY date_col) prev_day
    FROM 
        Calendar 
    WHERE 
        date_col BETWEEN sysdate - 6 AND sysdate -- spec period
) WHERE date_col - prev_day &gt; 1

huangapple
  • 本文由 发表于 2023年2月23日 20:16:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/75544715.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定