简体   繁体   English

Oracle SQL中的序列号

[英]Sequence number in Oracle SQL

Hi I have my table data as below. 嗨,我的表格数据如下。

Year    Period  Start_Date  End_Date
2019    6   1-Jun-19    30-Jun-19
2019    7   1-Jul-19    31-Jul-19

I want to fetch the data as below based on above. 我想基于上面获取以下数据。

hear period end date will be the Fridays between start_date and End_date in the above table. 听到期间结束日期将是上表中start_date和End_date之间的星期五。

Period  Sequence_no Period_end_dt
6        1           07-Jun-19
6        2           14-Jun-19
6        3           21-Jun-19
6        4           28-Jun-19
7        1           05-Jul-19
7        2           12-Jul-19
7        3           19-Jul-19
7        4           26-Jul-19

You can use a recursive CTE: 您可以使用递归CTE:

with cte(year, sequence_no, period_end_dt, end_dt) as (
      select year, period, 1 as sequence_no, start_date + 6 as period_end_dt, end_dt
      from t
      union all
      select year, period, sequence_no + 1, period_end_dt + 7 as period_end_dt, end_dt
      from t
      where period_end_dt + 7 < end_dt
     )
select year, period, sequence_no, period_end_dt
from t;

Another recursive CTE (11gR2+): 另一个递归CTE(11gR2 +):

with rcte (year, period, end_date, sequence_no, period_end_dt) as (
  select year, period, end_date, 1, next_day(start_date - 1, 'Friday')
  from your_table
  union all
  select year, period, end_date, sequence_no + 1, period_end_dt + 7
  from rcte
  where period_end_dt + 7 < end_date
)
select year, period, sequence_no, period_end_dt
from rcte
order by year, period, sequence_no;

      YEAR     PERIOD SEQUENCE_NO PERIOD_END
---------- ---------- ----------- ----------
      2019          6           1 2019-06-07
      2019          6           2 2019-06-14
      2019          6           3 2019-06-21
      2019          6           4 2019-06-28
      2019          7           1 2019-07-05
      2019          7           2 2019-07-12
      2019          7           3 2019-07-19
      2019          7           4 2019-07-26

The next_day() is passed the day before the start day, in case the start is actually a Friday. 如果开始实际上是星期五,则在开始日期的一天传递next_day() The downside is that the day name has to be passed int he session date language, and that can't be overridden as part of the function call. 缺点是必须在会话日期语言中传递日期名称,并且不能将其作为函数调用的一部分覆盖。 If that isn't acceptable you can manipulate the date using ISO weekday numbers, but it's a bit more work. 如果不可接受,您可以使用ISO工作日数字来操纵日期,但这需要更多工作。

with rcte (year, period, end_date, sequence_no, period_end_dt) as (
  select year, period, end_date, 1, trunc(start_date + 2, 'IW') + 4
  from your_table
  union all
  select year, period, end_date, sequence_no + 1, period_end_dt + 7
  from rcte
  where period_end_dt + 7 < end_date
)
select year, period, sequence_no, period_end_dt
from rcte
order by year, period, sequence_no;

      YEAR     PERIOD SEQUENCE_NO PERIOD_END
---------- ---------- ----------- ----------
      2019          6           1 2019-06-07
      2019          6           2 2019-06-14
      2019          6           3 2019-06-21
      2019          6           4 2019-06-28
      2019          7           1 2019-07-05
      2019          7           2 2019-07-12
      2019          7           3 2019-07-19
      2019          7           4 2019-07-26

db<>fiddle db <>小提琴

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM