希望我能解决问题的正义,因为在标题中总结它太难了! (评论中欢迎提出建议)
是的,所以这是我的表:
Tasks
task_id (number)
job_id (number)
to_do_by_date (date)
task_name (varchar / text)
status (number)
completed_date (date)
为了论证,让我们创建状态值:
1 = New
2 = InProgress
3 = Done
我正在尝试做的事情是创建一个可以回退所有任务的查询:
job_id
的任何任务都有status
<>完成
job_id
的所有任务都已完成,但一个或多个任务今天有completed_date
的情况to_be_done_by
日期排序,但将所有job_id任务分组在一起
job_id
有关数据的一些信息:
job_id
可以有任意数量的任务
以下是我想要获得的输出示例:
task_id job_id to_do_by_date task_name status completed_date
1 1 yesterday - 3 yesterday
2 1 today - 3 today
3 2 now - 3 today
4 2 2 hours time - 2 {null}
5 2 4 hours time - 2 {null}
6 2 tomorrow - 1 {null}
7 3 3 hours time - 2 {null}
8 3 tomorrow - 1 {null}
9 3 tomorrow - 1 {null}
我正在使用Oracle 10g,所以Oracle或ANSI SQL的答案,或者如何处理这个问题的提示都是理想的,我可以创建视图或将其包装在存储过程中,以便在您的解决方案需要时从应用程序中卸载逻辑它
这是一个sql脚本,它将创建上面显示的示例测试数据:
create table tasks (task_id number, job_id number, to_do_by_date date, task_name varchar2(50), status number, completed_date date);
insert into tasks values (0,0,sysdate -2, 'Job 0, Task 1 - dont return!', 3, sysdate -2);
insert into tasks values (1,1,sysdate -1, 'Job 1, Task 1', 3, sysdate -1);
insert into tasks values (2,1,sysdate -2/24, 'Job 1, Task 2', 3, sysdate -2/24);
insert into tasks values (3,2,sysdate, 'Job 2, Task 1', 3, sysdate);
insert into tasks values (4,2,sysdate +2/24, 'Job 2, Task 2', 2, null);
insert into tasks values (5,2,sysdate +4/24, 'Job 2, Task 3', 2, null);
insert into tasks values (6,2,sysdate +1, 'Job 2, Task 4', 1, null);
insert into tasks values (7,3,sysdate +3/24, 'Job 3, Task 1', 2, null);
insert into tasks values (8,3,sysdate +1, 'Job 3, Task 2', 1, null);
insert into tasks values (9,3,sysdate +1, 'Job 3, Task 3', 1, null);
commit;
很多,非常感谢你的帮助:o)
答案 0 :(得分:2)
显然你需要解决这个问题,但我希望你明白这一点。
SELECT
task_id, job_id, to_do_by_date, task_name, status, completed_date
FROM
Tasks
WHERE
job_id IN (
SELECT job_id
FROM Tasks
WHERE status <> 'Done'
GROUP BY job_id)
OR
job_id IN (
SELECT job_id
FROM Tasks
WHERE status = 'Done' AND completed_date = 'Today'
AND job_id NOT IN (SELECT job_id FROM Tasks WHERE status <> 'Done' GROUP BY job_id)
GROUP BY job_id)
ORDER BY
job_id, to_do_by_date
答案 1 :(得分:2)
我同意贾斯汀的说法 - 我不明白为什么要回归2。
这是一个使用分析函数根据逻辑描述返回正确行的查询。
select * from
(
select t.*,
min(status) over (partition by job_id) min_status_over_job,
max(status) over (partition by job_id) max_status_over_job,
sum(case when trunc(completed_date) = trunc(sysdate)-1 then 1 else 0 end)
over (partition by job_id) num_complete_yest
from tasks t
)
where max_status_over_job < 3
or (min_status_over_job = 3 and num_complete_yest > 0)
/
答案 2 :(得分:0)
鉴于您的要求,我不清楚为什么应该在结果中返回job_id 2。有一个状态为Done的任务,因此它未通过第一个标准
job_id的所有任务都有 状态&lt;&gt;完成
并且有些任务的状态不是Done,因此它没有达到第二个标准
除了job_id的所有任务 已完成,但一项或多项任务 有一个今天的completed_date
还有其他原因应该包括job_id = 2吗?
SQL> ed
Wrote file afiedt.buf
1 select task_id, job_id, to_do_by_date, task_name, status, completed_date
2 from tasks t1
3 where not exists( select 1
4 from tasks t2
5 where t1.job_id = t2.job_id
6 and t2.status = 3)
7 or ((not exists( select 1
8 from tasks t3
9 where t1.job_id = t3.job_id
10 and t3.status != 3))
11 and
12 exists (select 1
13 from tasks t4
14 where t1.job_id = t4.job_id
15 and trunc(t4.completed_date) = trunc(sysdate)))
16* order by job_id, to_do_by_date
SQL> /
TASK_ID JOB_ID TO_DO_BY_ TASK_NAME STATUS COMPLETED
---------- ---------- --------- --------------- ---------- ---------
1 1 28-OCT-08 Job 1, Task 1 3 28-OCT-08
2 1 29-OCT-08 Job 1, Task 2 3 29-OCT-08
7 3 29-OCT-08 Job 3, Task 1 2
8 3 30-OCT-08 Job 3, Task 2 1
9 3 30-OCT-08 Job 3, Task 3 1
答案 3 :(得分:0)
我不做Oracle,而且我没有方便的Sql Server - 但这应该让你相当接近。
SELECT Tasks.*
FROM Tasks
JOIN (
--Undone
SELECT Job_Id
FROM Tasks
WHERE
Status <> 3
UNION
--Done today
SELECT Job_Id
FROM Tasks
WHERE
Status = 3
AND Completed_Date = TODAY()
) as UndoneOrDoneToday ON
Tasks.Job_Id = UndoneOrDoneToday.Job_Id
JOIN (
SELECT Job_Id, MIN(to_do_by_date) as NextToDoByDate
FROM Tasks
GROUP BY Job_id
) as NextJob ON
Tasks.Job_Id = NextJob.Job_id
ORDER BY
NextJob.NextToDoByDate,
Tasks.Job_Id, --If NextToDoByDate isn't unique, this should order jobs together
Tasks.to_do_by_date, --This may not be needed, but would put eg., task 7 due today higher than task 6 due tomorrow
Tasks.Task_Id --this should be last
编辑:大多数其他答案似乎按job_id,to_do_by排序。这看起来适用于示例数据,但不符合以下要求:
按to_be_done_by日期排序,但将所有job_id任务分组在一起 因此,首先显示具有下一个to_do_by_date任务的job_id