Moh*_*lim 3 sql oracle oracle11g gaps-and-islands
我的桌子的日期是2015年11月2日至2015年12月1日.例如...
ATTNDATE
--------
02/11/2015
03/11/2015
--
--
--
01/12/2015.
Run Code Online (Sandbox Code Playgroud)
此表可能还有一些缺失日期.让我们假设此表中缺少06/11/2015和20/11/2015.
我希望得到像这样的输出
SL.No ATTNFROM ATTNTILL
1. 02/11/2015 05/11/2015
2. 07/11/2015 19/11/2015
3. 21/11/2015 01/12/2015
Run Code Online (Sandbox Code Playgroud)
请帮助我在oracle plsql中获取此输出
您可以使用超前和滞后分析函数来执行此操作 - 在子组中,然后将其分组,这可能是您错过的 - 但您也可以使用分析"技巧"来执行此操作.
如果你查看每个日期和最低日期之间的差异,你得到一个破碎的序列,在你的情况下,0,1,2,3,5,...,27,28,29.你可以看到attndate - min(attndate) over ().
你还有另一个完整的序列row_number() over (order by attndate),它给你1,2,3,... 28.
如果从另一个中减去一个,则每个连续的日期块都会得到相同的答案,我称之为'slot_no':
select attndate,
attndate - min(attndate) over ()
- row_number() over (order by attndate) as slot_no
from your_table;
Run Code Online (Sandbox Code Playgroud)
使用这些数据,每一行都会得到-1,0或1.(如果需要,可以添加两行以使它们更友好,但只有在数据中的间隙为单日时才能正常工作).然后,您可以按该插槽号分组:
with cte as (
select attndate,
attndate - min(attndate) over ()
- row_number() over (order by attndate) as slot_no
from your_table
)
select dense_rank() over (order by slot_no) as slot_no,
min(attndate) as attnfrom, max(attndate) as attntill
from cte
group by slot_no
order by slot_no;
Run Code Online (Sandbox Code Playgroud)
使用一些生成的数据:
alter session set nls_date_format = 'DD/MM/YYYY';
with your_table (attndate) as (
select date '2015-11-02' + level - 1 from dual connect by level <= 4
union all select date '2015-11-07' + level - 1 from dual connect by level <= 13
union all select date '2015-11-21' + level - 1 from dual connect by level <= 11
),
cte as (
select attndate,
attndate - min(attndate) over ()
- row_number() over (order by attndate) as slot_no
from your_table
)
select dense_rank() over (order by slot_no) as slot_no,
min(attndate) as attnfrom, max(attndate) as attntill
from cte
group by slot_no
order by slot_no;
SLOT_NO ATTNFROM ATTNTILL
---------- ---------- ----------
1 02/11/2015 05/11/2015
2 07/11/2015 19/11/2015
3 21/11/2015 01/12/2015
Run Code Online (Sandbox Code Playgroud)
如果您的真实场景是获取多个键的这些范围,例如人员ID,那么您可以partition by在三个over ()部分中为每个分析函数调用添加一个子句.
| 归档时间: |
|
| 查看次数: |
123 次 |
| 最近记录: |