Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.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中的缺口和孤岛解决方案-使用递归_Oracle_Plsql_Group By - Fatal编程技术网

Oracle中的缺口和孤岛解决方案-使用递归

Oracle中的缺口和孤岛解决方案-使用递归,oracle,plsql,group-by,Oracle,Plsql,Group By,我有一个问题,在Oracle中使用游标可以很容易地解决。但是,我想知道是否可以只使用select来实现这一点。我有一个包含以下字段的数据集:开始、描述、MaximumRow、SequentialOrder 数据集按描述、开始、顺序排序。这是用于说明的数据: 我希望在不同的数据集中得到以下结果 (开始、结束、说明),其中开始是集合中“开始”字段的最小值,结束是集合中“开始”字段的最大值。该集合由以下规则定义: 新集合中的总行数不超过上一集合中定义的maximumrow,并且新集合中的所有行都按顺

我有一个问题,在Oracle中使用游标可以很容易地解决。但是,我想知道是否可以只使用select来实现这一点。我有一个包含以下字段的数据集:开始、描述、MaximumRow、SequentialOrder

数据集按描述、开始、顺序排序。这是用于说明的数据:

我希望在不同的数据集中得到以下结果 (开始、结束、说明),其中开始是集合中“开始”字段的最小值,结束是集合中“开始”字段的最大值。该集合由以下规则定义: 新集合中的总行数不超过上一集合中定义的maximumrow,并且新集合中的所有行都按顺序排序

根据上述规则,我有以下几套:

因此,我希望看到的基于插图的结果是

12-Jun-15, 14-Jun-15, A
01-Jul-15, 01-Jul-15, A
02-Jul-15, 04-Jul-15, A
01-Aug-15, 16-Aug-15, B
如果可以的话,请告知。我知道我们可以根据描述进行分组,但我不知道我们是否可以根据MaximumRow和SequentialOrder进行进一步分组:如上所述,要评估的子集中的总行不能超过MaximumRow,并且必须按SequentialOrder进行排序

我不认为不使用游标就可以做到这一点,但我还是要问,以防万一

我已附加脚本以生成上面的示例:

  CREATE TABLE "TEST" 
   (    "Start" DATE, 
    "Description" VARCHAR2(20 BYTE), 
    "MaximunRow" NUMBER, 
    "SequentialOrder" NUMBER
   ) 
SET DEFINE OFF;
Insert into TEST ("Start","Description","MaximunRow","SequentialOrder") values (to_date('12-JUN-15','DD-MON-RR'),'A',3,3);
Insert into TEST ("Start","Description","MaximunRow","SequentialOrder") values (to_date('13-JUN-15','DD-MON-RR'),'A',3,4);
Insert into TEST ("Start","Description","MaximunRow","SequentialOrder") values (to_date('14-JUN-15','DD-MON-RR'),'A',3,5);
Insert into TEST ("Start","Description","MaximunRow","SequentialOrder") values (to_date('01-JUL-15','DD-MON-RR'),'A',3,4);
Insert into TEST ("Start","Description","MaximunRow","SequentialOrder") values (to_date('02-JUL-15','DD-MON-RR'),'A',3,3);
Insert into TEST ("Start","Description","MaximunRow","SequentialOrder") values (to_date('04-JUL-15','DD-MON-RR'),'A',3,4);
Insert into TEST ("Start","Description","MaximunRow","SequentialOrder") values (to_date('01-AUG-15','DD-MON-RR'),'B',2,5);
Insert into TEST ("Start","Description","MaximunRow","SequentialOrder") values (to_date('16-AUG-15','DD-MON-RR'),'B',2,7);

这是间隙和孤岛问题的一种变体,每个孤岛中的最大行数增加了复杂性。这有点冗长,但您可以从识别序列顺序导致的组开始:

select t.*,
  row_number() over (partition by "Description" order by "Start") as rn,
  case when lag("SequentialOrder")
    over (partition by "Description" order by "Start") < "SequentialOrder"
    then 1 else 0 end as newblock
from test t
order by "Start";

Start     Description MaximunRow SequentialOrder  RN   NEWBLOCK
--------- ----------- ---------- --------------- --- ----------
12-JUN-15 A                    3               3   1          0
13-JUN-15 A                    3               4   2          1
14-JUN-15 A                    3               5   3          1
01-JUL-15 A                    3               4   4          0
02-JUL-15 A                    3               3   5          0
04-JUL-15 A                    3               4   6          1
01-AUG-15 B                    2               5   1          0
16-AUG-15 B                    2               7   2          1
您的示例数据不会触发最大行中断,因为您没有任何长度超过3的序列。还有一些额外的数据:

Insert into TEST ("Start","Description","MaximunRow","SequentialOrder") values (to_date('15-JUN-15','DD-MON-RR'),'A',3,7);
Insert into TEST ("Start","Description","MaximunRow","SequentialOrder") values (to_date('16-JUN-15','DD-MON-RR'),'A',3,8);
Insert into TEST ("Start","Description","MaximunRow","SequentialOrder") values (to_date('17-JUN-15','DD-MON-RR'),'A',3,10);
Insert into TEST ("Start","Description","MaximunRow","SequentialOrder") values (to_date('18-JUN-15','DD-MON-RR'),'A',3,12);
Insert into TEST ("Start","Description","MaximunRow","SequentialOrder") values (to_date('19-JUN-15','DD-MON-RR'),'A',3,13);
相同的查询得到:

Start     End       Description
--------- --------- -----------
12-JUN-15 14-JUN-15 A          
15-JUN-15 17-JUN-15 A          
18-JUN-15 19-JUN-15 A          
01-JUL-15 01-JUL-15 A          
02-JUL-15 04-JUL-15 A          
01-AUG-15 16-AUG-15 B          
所以你可以看到它在序列改变时分裂,在块中击中三行时分裂


通过直接比较case语句中的顺序顺序,而不是使用
newblock
,您可以只使用递归CTE,而不是之前的中间CTE;但是让
rn
查找下一行比试图查找下一个日期更容易,因为它们不是连续的。

这是间隙和孤岛问题的一种变体,每个孤岛中的最大行数增加了复杂性。这有点冗长,但您可以从识别序列顺序导致的组开始:

select t.*,
  row_number() over (partition by "Description" order by "Start") as rn,
  case when lag("SequentialOrder")
    over (partition by "Description" order by "Start") < "SequentialOrder"
    then 1 else 0 end as newblock
from test t
order by "Start";

Start     Description MaximunRow SequentialOrder  RN   NEWBLOCK
--------- ----------- ---------- --------------- --- ----------
12-JUN-15 A                    3               3   1          0
13-JUN-15 A                    3               4   2          1
14-JUN-15 A                    3               5   3          1
01-JUL-15 A                    3               4   4          0
02-JUL-15 A                    3               3   5          0
04-JUL-15 A                    3               4   6          1
01-AUG-15 B                    2               5   1          0
16-AUG-15 B                    2               7   2          1
您的示例数据不会触发最大行中断,因为您没有任何长度超过3的序列。还有一些额外的数据:

Insert into TEST ("Start","Description","MaximunRow","SequentialOrder") values (to_date('15-JUN-15','DD-MON-RR'),'A',3,7);
Insert into TEST ("Start","Description","MaximunRow","SequentialOrder") values (to_date('16-JUN-15','DD-MON-RR'),'A',3,8);
Insert into TEST ("Start","Description","MaximunRow","SequentialOrder") values (to_date('17-JUN-15','DD-MON-RR'),'A',3,10);
Insert into TEST ("Start","Description","MaximunRow","SequentialOrder") values (to_date('18-JUN-15','DD-MON-RR'),'A',3,12);
Insert into TEST ("Start","Description","MaximunRow","SequentialOrder") values (to_date('19-JUN-15','DD-MON-RR'),'A',3,13);
相同的查询得到:

Start     End       Description
--------- --------- -----------
12-JUN-15 14-JUN-15 A          
15-JUN-15 17-JUN-15 A          
18-JUN-15 19-JUN-15 A          
01-JUL-15 01-JUL-15 A          
02-JUL-15 04-JUL-15 A          
01-AUG-15 16-AUG-15 B          
所以你可以看到它在序列改变时分裂,在块中击中三行时分裂


通过直接比较case语句中的顺序顺序,而不是使用
newblock
,您可以只使用递归CTE,而不是之前的中间CTE;但是让
rn
查找下一行比试图查找下一个日期更容易,因为它们不是连续的。

这是间隙和孤岛问题的一种变体,每个孤岛中的最大行数增加了复杂性。这有点冗长,但您可以从识别序列顺序导致的组开始:

select t.*,
  row_number() over (partition by "Description" order by "Start") as rn,
  case when lag("SequentialOrder")
    over (partition by "Description" order by "Start") < "SequentialOrder"
    then 1 else 0 end as newblock
from test t
order by "Start";

Start     Description MaximunRow SequentialOrder  RN   NEWBLOCK
--------- ----------- ---------- --------------- --- ----------
12-JUN-15 A                    3               3   1          0
13-JUN-15 A                    3               4   2          1
14-JUN-15 A                    3               5   3          1
01-JUL-15 A                    3               4   4          0
02-JUL-15 A                    3               3   5          0
04-JUL-15 A                    3               4   6          1
01-AUG-15 B                    2               5   1          0
16-AUG-15 B                    2               7   2          1
您的示例数据不会触发最大行中断,因为您没有任何长度超过3的序列。还有一些额外的数据:

Insert into TEST ("Start","Description","MaximunRow","SequentialOrder") values (to_date('15-JUN-15','DD-MON-RR'),'A',3,7);
Insert into TEST ("Start","Description","MaximunRow","SequentialOrder") values (to_date('16-JUN-15','DD-MON-RR'),'A',3,8);
Insert into TEST ("Start","Description","MaximunRow","SequentialOrder") values (to_date('17-JUN-15','DD-MON-RR'),'A',3,10);
Insert into TEST ("Start","Description","MaximunRow","SequentialOrder") values (to_date('18-JUN-15','DD-MON-RR'),'A',3,12);
Insert into TEST ("Start","Description","MaximunRow","SequentialOrder") values (to_date('19-JUN-15','DD-MON-RR'),'A',3,13);
相同的查询得到:

Start     End       Description
--------- --------- -----------
12-JUN-15 14-JUN-15 A          
15-JUN-15 17-JUN-15 A          
18-JUN-15 19-JUN-15 A          
01-JUL-15 01-JUL-15 A          
02-JUL-15 04-JUL-15 A          
01-AUG-15 16-AUG-15 B          
所以你可以看到它在序列改变时分裂,在块中击中三行时分裂


通过直接比较case语句中的顺序顺序,而不是使用
newblock
,您可以只使用递归CTE,而不是之前的中间CTE;但是让
rn
查找下一行比试图查找下一个日期更容易,因为它们不是连续的。

这是间隙和孤岛问题的一种变体,每个孤岛中的最大行数增加了复杂性。这有点冗长,但您可以从识别序列顺序导致的组开始:

select t.*,
  row_number() over (partition by "Description" order by "Start") as rn,
  case when lag("SequentialOrder")
    over (partition by "Description" order by "Start") < "SequentialOrder"
    then 1 else 0 end as newblock
from test t
order by "Start";

Start     Description MaximunRow SequentialOrder  RN   NEWBLOCK
--------- ----------- ---------- --------------- --- ----------
12-JUN-15 A                    3               3   1          0
13-JUN-15 A                    3               4   2          1
14-JUN-15 A                    3               5   3          1
01-JUL-15 A                    3               4   4          0
02-JUL-15 A                    3               3   5          0
04-JUL-15 A                    3               4   6          1
01-AUG-15 B                    2               5   1          0
16-AUG-15 B                    2               7   2          1
您的示例数据不会触发最大行中断,因为您没有任何长度超过3的序列。还有一些额外的数据:

Insert into TEST ("Start","Description","MaximunRow","SequentialOrder") values (to_date('15-JUN-15','DD-MON-RR'),'A',3,7);
Insert into TEST ("Start","Description","MaximunRow","SequentialOrder") values (to_date('16-JUN-15','DD-MON-RR'),'A',3,8);
Insert into TEST ("Start","Description","MaximunRow","SequentialOrder") values (to_date('17-JUN-15','DD-MON-RR'),'A',3,10);
Insert into TEST ("Start","Description","MaximunRow","SequentialOrder") values (to_date('18-JUN-15','DD-MON-RR'),'A',3,12);
Insert into TEST ("Start","Description","MaximunRow","SequentialOrder") values (to_date('19-JUN-15','DD-MON-RR'),'A',3,13);
相同的查询得到:

Start     End       Description
--------- --------- -----------
12-JUN-15 14-JUN-15 A          
15-JUN-15 17-JUN-15 A          
18-JUN-15 19-JUN-15 A          
01-JUL-15 01-JUL-15 A          
02-JUL-15 04-JUL-15 A          
01-AUG-15 16-AUG-15 B          
所以你可以看到它在序列改变时分裂,在块中击中三行时分裂


通过直接比较case语句中的顺序顺序,而不是使用
newblock
,您可以只使用递归CTE,而不是之前的中间CTE;但是让
rn
查找下一行要比查找下一个日期容易,因为它们不是连续的。

您看过吗?此外,您还没有显示最大行限制有任何影响的任何数据或结果;无论如何,你最长的顺序跑是3次。也许你可以展示一些长时间运行和不同最大值的变化,以及组是如何受到影响的?第一组中的最大行数是多少,因为之前没有一组可以从中获取该值?@AlexPoole:最大行数包含在MaximumRow字段中,但你说“新集合中的总行数不超过上一集合中定义的最大行数“。对于从2015年6月12日开始的第一个集合,没有以前的集合,因此它没有最大大小,还是默认为自己的值?顺便问一下,对于构成集合的所有行来说,这个值都是相同的吗?那么,您是否仍然对这个问题的解决方案感兴趣,但不使用递归查询?不清楚-你昨天贴了一些东西,然后又把它拉了回来。你看过了吗?此外,您还没有显示最大行限制有任何影响的任何数据或结果;无论如何,你最长的顺序跑是3次。也许你可以展示一些长时间运行和不同最大值的变化,以及组是如何受到影响的?由于没有pr,第一组中的最大行数是多少