您好我有以下查询...
我希望有一个以下数据集,只有4列,可以查询以获取项目。项目由前一行分隔,不具有与当前行start_date相同的end_date。所以前三行将在同一个项目中。第二个项目是接下来的两行,项目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查询中遇到错误。以下是我迄今为止在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 Clause。我认为oracle dba可能会处理这个问题吗?我顺便使用11g Express。
答案 0 :(得分:2)
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
答案 1 :(得分: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;
<强> 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