Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
需要Oracle sql查询来对日期进行分组_Sql_Oracle_Oracle11g_Gaps And Islands - Fatal编程技术网

需要Oracle sql查询来对日期进行分组

需要Oracle sql查询来对日期进行分组,sql,oracle,oracle11g,gaps-and-islands,Sql,Oracle,Oracle11g,Gaps And Islands,我有一张日期为2015年11月2日至2015年12月1日的表格。 例如 此表可能还缺少一些日期。。假设此表中缺少2015年11月6日和2015年11月20日 我想得到像这样的输出 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 请

我有一张日期为2015年11月2日至2015年12月1日的表格。 例如

此表可能还缺少一些日期。。假设此表中缺少2015年11月6日和2015年11月20日

我想得到像这样的输出

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

请帮助我在oracle plsql中获得此输出,您可以使用超前和滞后分析函数来完成此操作-在子查询中进行分组,这可能是您错过的-但您也可以使用分析“技巧”来完成此操作

如果你看每个日期和最低日期之间的差异,你会得到一个不连续的序列,在你的例子中是0,1,2,3,5,…,27,28,29。你可以看到,随着attndate的结束

您还可以从attndate的order上的row_number获得另一个未中断的序列,它为您提供了1、2、3。。。二十八,

如果你从另一个中减去一个,每个连续的日期块都会得到相同的答案,我称之为“slot_no”:

select attndate,
  attndate - min(attndate) over ()
    - row_number() over (order by attndate) as slot_no
from your_table;
有了这些数据,每一行都会得到-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;
使用一些生成的数据:

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

如果您的实际场景是获取多个键的这些范围,比如一个person ID,那么您可以在三个以上部分中为每个分析函数调用添加一个partition by子句。

您已经尝试了什么?有什么想法吗?你需要的是超前或滞后分析函数,它将每个日期连接到下一个或最后一个日期。然后检查间隙是否大于1Hi。。我正在使用游标获取表列表。。然后我将2015年11月2日作为第一条记录插入ATTNFROM列中。。然后我将更新ATNTILL以获得剩余的循环。。但我不能像我之前提到的那样录制…嗨,sagi,我尝试了滞后功能。。它给出了每天和前一天的输出,但没有给出我上面提到的输出。请编辑您的问题,并包括您编写的代码,也许有人可以帮助纠正它。亚历克斯·普尔:谢谢你提供的信息。。我已经得到了我的产出。。再次感谢你
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