Sql Oracle中的递归查询

Sql Oracle中的递归查询,sql,oracle,oracle11g,recursive-query,Sql,Oracle,Oracle11g,Recursive Query,你好,我有以下问题 我想查询以下数据集(只有4列)以获取项目。项目由前一行分隔,前一行的结束日期与当前行的开始日期不相同。所以前三行将在同一个项目中。第二个项目将是接下来的两行,项目3和4将是倒数第二行和最后一行 DAYS,TASK_ID,START_DATE,END_DATE NULL,1,10/1/2015,10/2/2015 0,2,10/2/2015,10/3/2015 0,3,10/3/2015,10/4/2015 9,4,10/13/2015,10/14/2015 0,5,10/14

你好,我有以下问题

我想查询以下数据集(只有4列)以获取项目。项目由前一行分隔,前一行的结束日期与当前行的开始日期不相同。所以前三行将在同一个项目中。第二个项目将是接下来的两行,项目3和4将是倒数第二行和最后一行

DAYS,TASK_ID,START_DATE,END_DATE
NULL,1,10/1/2015,10/2/2015
0,2,10/2/2015,10/3/2015
0,3,10/3/2015,10/4/2015
9,4,10/13/2015,10/14/2015
0,5,10/14/2015,10/15/2015
13,6,10/28/2015,10/29/2015
1,7,10/30/2015,10/31/2015
所以输出看起来像

PROJECT,DAYS,TASK_ID,START_DATE,END_DATE
1,NULL,1,10/1/2015,10/2/2015
1,0,2,10/2/2015,10/3/2015
1,0,3,10/3/2015,10/4/2015
2,9,4,10/13/2015,10/14/2015
2,0,5,10/14/2015,10/15/2015
3,13,6,10/28/2015,10/29/2015
4,1,7,10/30/2015,10/31/2015
我是一名sql server架构师,我已经完成了sql server查询,但是我在oracle查询中遇到了错误。以下是我目前在甲骨文中所做的

WITH projectsNumbered (Project, Task_Id, Start_Date, End_Date, Days) AS
(SELECT 1 As "Project"
      , Task_Id
      , Start_Date
      , End_Date
      , Days
  FROM daysBetweenTasks
  WHERE Task_Id = 1
  UNION ALL
  SELECT 
        CASE WHEN COALESCE(pN.Days,0) = 0 THEN pN.Project
             ELSE pN.Project + 1
        END AS "Project"
      , pN.Task_Id
      , pN.Start_Date
      , pN.End_Date
      , pN.Days
  FROM projectsNumbered pN 
    JOIN daysBetweenTasks d on p.task_Id = pN.task_Id + 1
)
--SEARCH DEPTH FIRST BY Task_Id SET order1
CYCLE Task_Id SET cycle TO '1' DEFAULT 0
SELECT * 
FROM projectsNumbered

但我只返回了两行。在出现错误后,我添加了Cycle子句。我认为oracle dba可能可以处理这个问题?顺便说一下,我用的是11g快车

Oracle安装程序:

CREATE TABLE daysBetweenTasks ( DAYS,TASK_ID,START_DATE,END_DATE ) AS
SELECT NULL, 1, DATE '2015-10-01', DATE '2015-10-02' FROM DUAL UNION ALL
SELECT 0,    2, DATE '2015-10-02', DATE '2015-10-03' FROM DUAL UNION ALL
SELECT 0,    3, DATE '2015-10-03', DATE '2015-10-04' FROM DUAL UNION ALL
SELECT 9,    4, DATE '2015-10-13', DATE '2015-10-14' FROM DUAL UNION ALL
SELECT 0,    5, DATE '2015-10-14', DATE '2015-10-15' FROM DUAL UNION ALL
SELECT 13,   6, DATE '2015-10-28', DATE '2015-10-29' FROM DUAL UNION ALL
SELECT 1,    7, DATE '2015-10-30', DATE '2015-10-31' FROM DUAL;
SELECT DENSE_RANK() OVER ( ORDER BY CONNECT_BY_ROOT( task_id ) ) AS project,
       days,
       task_id,
       start_date,
       end_date
FROM   (
  SELECT d.*,
         LAG( end_date ) OVER ( ORDER BY task_id ) AS prev_end_date
  FROM   daysBetweenTasks d
) d
START WITH prev_end_date IS NULL
OR         prev_end_date <> start_date
CONNECT BY PRIOR end_date = start_date;
   PROJECT       DAYS    TASK_ID START_DATE          END_DATE          
---------- ---------- ---------- ------------------- -------------------
         1                     1 2015-10-01 00:00:00 2015-10-02 00:00:00 
         1          0          2 2015-10-02 00:00:00 2015-10-03 00:00:00 
         1          0          3 2015-10-03 00:00:00 2015-10-04 00:00:00 
         2          9          4 2015-10-13 00:00:00 2015-10-14 00:00:00 
         2          0          5 2015-10-14 00:00:00 2015-10-15 00:00:00 
         3         13          6 2015-10-28 00:00:00 2015-10-29 00:00:00 
         4          1          7 2015-10-30 00:00:00 2015-10-31 00:00:00 
查询

CREATE TABLE daysBetweenTasks ( DAYS,TASK_ID,START_DATE,END_DATE ) AS
SELECT NULL, 1, DATE '2015-10-01', DATE '2015-10-02' FROM DUAL UNION ALL
SELECT 0,    2, DATE '2015-10-02', DATE '2015-10-03' FROM DUAL UNION ALL
SELECT 0,    3, DATE '2015-10-03', DATE '2015-10-04' FROM DUAL UNION ALL
SELECT 9,    4, DATE '2015-10-13', DATE '2015-10-14' FROM DUAL UNION ALL
SELECT 0,    5, DATE '2015-10-14', DATE '2015-10-15' FROM DUAL UNION ALL
SELECT 13,   6, DATE '2015-10-28', DATE '2015-10-29' FROM DUAL UNION ALL
SELECT 1,    7, DATE '2015-10-30', DATE '2015-10-31' FROM DUAL;
SELECT DENSE_RANK() OVER ( ORDER BY CONNECT_BY_ROOT( task_id ) ) AS project,
       days,
       task_id,
       start_date,
       end_date
FROM   (
  SELECT d.*,
         LAG( end_date ) OVER ( ORDER BY task_id ) AS prev_end_date
  FROM   daysBetweenTasks d
) d
START WITH prev_end_date IS NULL
OR         prev_end_date <> start_date
CONNECT BY PRIOR end_date = start_date;
   PROJECT       DAYS    TASK_ID START_DATE          END_DATE          
---------- ---------- ---------- ------------------- -------------------
         1                     1 2015-10-01 00:00:00 2015-10-02 00:00:00 
         1          0          2 2015-10-02 00:00:00 2015-10-03 00:00:00 
         1          0          3 2015-10-03 00:00:00 2015-10-04 00:00:00 
         2          9          4 2015-10-13 00:00:00 2015-10-14 00:00:00 
         2          0          5 2015-10-14 00:00:00 2015-10-15 00:00:00 
         3         13          6 2015-10-28 00:00:00 2015-10-29 00:00:00 
         4          1          7 2015-10-30 00:00:00 2015-10-31 00:00:00 

Oracle安装程序

CREATE TABLE daysBetweenTasks ( DAYS,TASK_ID,START_DATE,END_DATE ) AS
SELECT NULL, 1, DATE '2015-10-01', DATE '2015-10-02' FROM DUAL UNION ALL
SELECT 0,    2, DATE '2015-10-02', DATE '2015-10-03' FROM DUAL UNION ALL
SELECT 0,    3, DATE '2015-10-03', DATE '2015-10-04' FROM DUAL UNION ALL
SELECT 9,    4, DATE '2015-10-13', DATE '2015-10-14' FROM DUAL UNION ALL
SELECT 0,    5, DATE '2015-10-14', DATE '2015-10-15' FROM DUAL UNION ALL
SELECT 13,   6, DATE '2015-10-28', DATE '2015-10-29' FROM DUAL UNION ALL
SELECT 1,    7, DATE '2015-10-30', DATE '2015-10-31' FROM DUAL;
SELECT DENSE_RANK() OVER ( ORDER BY CONNECT_BY_ROOT( task_id ) ) AS project,
       days,
       task_id,
       start_date,
       end_date
FROM   (
  SELECT d.*,
         LAG( end_date ) OVER ( ORDER BY task_id ) AS prev_end_date
  FROM   daysBetweenTasks d
) d
START WITH prev_end_date IS NULL
OR         prev_end_date <> start_date
CONNECT BY PRIOR end_date = start_date;
   PROJECT       DAYS    TASK_ID START_DATE          END_DATE          
---------- ---------- ---------- ------------------- -------------------
         1                     1 2015-10-01 00:00:00 2015-10-02 00:00:00 
         1          0          2 2015-10-02 00:00:00 2015-10-03 00:00:00 
         1          0          3 2015-10-03 00:00:00 2015-10-04 00:00:00 
         2          9          4 2015-10-13 00:00:00 2015-10-14 00:00:00 
         2          0          5 2015-10-14 00:00:00 2015-10-15 00:00:00 
         3         13          6 2015-10-28 00:00:00 2015-10-29 00:00:00 
         4          1          7 2015-10-30 00:00:00 2015-10-31 00:00:00 
查询

CREATE TABLE daysBetweenTasks ( DAYS,TASK_ID,START_DATE,END_DATE ) AS
SELECT NULL, 1, DATE '2015-10-01', DATE '2015-10-02' FROM DUAL UNION ALL
SELECT 0,    2, DATE '2015-10-02', DATE '2015-10-03' FROM DUAL UNION ALL
SELECT 0,    3, DATE '2015-10-03', DATE '2015-10-04' FROM DUAL UNION ALL
SELECT 9,    4, DATE '2015-10-13', DATE '2015-10-14' FROM DUAL UNION ALL
SELECT 0,    5, DATE '2015-10-14', DATE '2015-10-15' FROM DUAL UNION ALL
SELECT 13,   6, DATE '2015-10-28', DATE '2015-10-29' FROM DUAL UNION ALL
SELECT 1,    7, DATE '2015-10-30', DATE '2015-10-31' FROM DUAL;
SELECT DENSE_RANK() OVER ( ORDER BY CONNECT_BY_ROOT( task_id ) ) AS project,
       days,
       task_id,
       start_date,
       end_date
FROM   (
  SELECT d.*,
         LAG( end_date ) OVER ( ORDER BY task_id ) AS prev_end_date
  FROM   daysBetweenTasks d
) d
START WITH prev_end_date IS NULL
OR         prev_end_date <> start_date
CONNECT BY PRIOR end_date = start_date;
   PROJECT       DAYS    TASK_ID START_DATE          END_DATE          
---------- ---------- ---------- ------------------- -------------------
         1                     1 2015-10-01 00:00:00 2015-10-02 00:00:00 
         1          0          2 2015-10-02 00:00:00 2015-10-03 00:00:00 
         1          0          3 2015-10-03 00:00:00 2015-10-04 00:00:00 
         2          9          4 2015-10-13 00:00:00 2015-10-14 00:00:00 
         2          0          5 2015-10-14 00:00:00 2015-10-15 00:00:00 
         3         13          6 2015-10-28 00:00:00 2015-10-29 00:00:00 
         4          1          7 2015-10-30 00:00:00 2015-10-31 00:00:00 

您在查询中遇到了一个错误,因为在联合体的下方,您使用的是pN.task_id而不是d.task_id,这是一个无限循环。 它应该是这样的:

    WITH projectsNumbered (Project, Task_Id, Start_Date, End_Date, Days) AS
(SELECT 1 As "Project"
      , Task_Id
      , Start_Date
      , End_Date
      , Days
  FROM daysBetweenTasks
  WHERE Task_Id = 1
  UNION ALL
  SELECT 
        CASE WHEN COALESCE(d.Days,0) = 0 THEN pN.Project
             ELSE pN.Project + 1
        END AS "Project"
      , d.Task_Id
      , d.Start_Date
      , d.End_Date
      , d.Days
  FROM projectsNumbered pN 
    JOIN daysBetweenTasks d on d.task_Id = pN.task_Id + 1
)
SELECT * 
FROM projectsNumbered;
输出

PROJECT    TASK_ID  START_DATE  END_DATE    DAYS  
1          1        01-OCT-15   02-OCT-15         
1          2        02-OCT-15   03-OCT-15   0     
1          3        03-OCT-15   04-OCT-15   0     
2          4        13-OCT-15   14-OCT-15   9     
2          5        14-OCT-15   15-OCT-15   0     
3          6        28-OCT-15   29-OCT-15   13    
4          7        30-OCT-15   31-OCT-15   1     

您在查询中遇到了一个错误,因为在联合体的下方,您使用的是pN.task_id而不是d.task_id,这是一个无限循环。 它应该是这样的:

    WITH projectsNumbered (Project, Task_Id, Start_Date, End_Date, Days) AS
(SELECT 1 As "Project"
      , Task_Id
      , Start_Date
      , End_Date
      , Days
  FROM daysBetweenTasks
  WHERE Task_Id = 1
  UNION ALL
  SELECT 
        CASE WHEN COALESCE(d.Days,0) = 0 THEN pN.Project
             ELSE pN.Project + 1
        END AS "Project"
      , d.Task_Id
      , d.Start_Date
      , d.End_Date
      , d.Days
  FROM projectsNumbered pN 
    JOIN daysBetweenTasks d on d.task_Id = pN.task_Id + 1
)
SELECT * 
FROM projectsNumbered;
输出

PROJECT    TASK_ID  START_DATE  END_DATE    DAYS  
1          1        01-OCT-15   02-OCT-15         
1          2        02-OCT-15   03-OCT-15   0     
1          3        03-OCT-15   04-OCT-15   0     
2          4        13-OCT-15   14-OCT-15   9     
2          5        14-OCT-15   15-OCT-15   0     
3          6        28-OCT-15   29-OCT-15   13    
4          7        30-OCT-15   31-OCT-15   1     

您知道如何在类似sql server的递归查询中使用它吗?使用cte的锚定部分和递归部分?您知道如何在类似sql server的递归查询中使用它吗?对于cte的锚定部分和递归部分?谢谢,伙计,我实际上是这样做的,但是我的列顺序不正确。它只给了我一排作为回报。最疯狂的错误人,比如一个努伯汉克斯人,我实际上是在这样做,但我的专栏顺序不正确。它只给了我一排作为回报。最疯狂的错误就是这样一个傻瓜