2016-05-31 8 views
0

Hallo ich die folgende Abfrage haben ...rekursive Abfrage in Oracle

Ich möchte eine der folgenden Datensatz haben, die nur 4 Spalten, abgefragt werden, um das Projekt zu erhalten. Die Projekte werden durch die vorherige Zeile getrennt, die nicht das gleiche Enddatum wie die aktuelle Zeile start_date hat. Die ersten drei Zeilen wären also im selben Projekt. Das zweite Projekt wären die nächsten zwei Zeilen und die Projekte 3 und 4 wären die vorletzten und letzten Zeilen.

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 

So würde die Ausgabe aussieht

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 

ich ein SQL Server-Architekt bin, und ich habe bereits die SQL Server-Abfrage, aber ich bin Fehler auf der Oracle-Abfrage zu bekommen. Hier ist, was ich bisher in Oracle habe.

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 

Aber ich bekomme nur zwei Zeilen zurück. Ich habe die Zyklusklausel hinzugefügt, nachdem ein Fehler aufgetreten ist. Ich denke, dass ein Orakel dba mit diesem umgehen könnte? Ich benutze übrigens 11g Express.

Antwort

2

Oracle-Setup:

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; 

Abfrage:

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; 

Ausgang:

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 
+0

Wissen Sie, wie Sie es in einer rekursiven SQL Server wie Abfrage verwenden würde? Mit den Anker- und rekursiven Teilen der Cte? –

1

Sie erhalten einen Fehler o In der Abfrage seit auf der unteren Seite der Union alle verwenden Sie pN.task_id anstelle von d.task_id und das ist eine Endlosschleife. Diese ist, was es sollte wie folgt aussehen:

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; 

OUPUT

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  
+1

Danke Mann, ich tat das eigentlich, aber ich hatte die Spalten falsch bestellt. Es gab mir nur eine Reihe als Gegenleistung. Der verrückteste Fehlermann wie ein Noob –