希望我能公正地解决问题,因为很难在标题中概括它!(建议欢迎在评论中提出) 对,所以这里是我的表: Tasks task_id (number) job_id (number) to_do_by_date (date) task_name (varchar / text) status (number) completed_date (date) 为了论证,让我们确定status的值: 1 = New 2 = InProgress 3 = Done 我在尝试执行时遇到的麻烦是创建一个可以拉回所有任务的查询: 其中任何一项任务job_id的status<>完成 除非a的所有任务job_id均已完成,但一个或多个任务completed_date的今天为a 按to_be_done_by日期排序,但将所有job_id任务分组在一起 因此,job_id首先显示下一个“ to_do_by_date”任务的 有关数据的一些信息: 一个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)
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
要实现您的需求,可以使用Oracle的分析函数和窗口函数来分组和过滤数据。以下是一个可能的SQL查询示例,它应该能根据您的描述生成所需的输出:
WITH TaskStatus AS (
SELECT
task_id,
job_id,
to_do_by_date,
task_name,
status,
completed_date,
-- 计算job_id级别的完成状态,如果所有任务都完成则为1,否则为0
MAX(CASE WHEN status = 3 THEN 1 ELSE 0 END) OVER (PARTITION BY job_id) AS all_done,
-- 找出每个job_id下最近的completed_date
MAX(completed_date) OVER (PARTITION BY job_id) AS latest_completed_date
FROM tasks
),
FilteredTasks AS (
SELECT
task_id,
job_id,
to_do_by_date,
task_name,
status,
completed_date
FROM TaskStatus
WHERE
-- 筛选出那些不是所有任务都完成的,或者完成了但有任务在今天完成的
(all_done = 0 OR (all_done = 1 AND latest_completed_date = TRUNC(SYSDATE)))
)
SELECT *
FROM FilteredTasks
ORDER BY job_id, to_do_by_date;
这个查询分为两部分: 1. TaskStatus CTE(公共表表达式)首先计算每个job_id
的所有任务是否全部完成(通过MAX(CASE WHEN status = 3 THEN 1 ELSE 0 END)
),并找出每个job_id
下的最新完成日期。 2. FilteredTasks CTE基于TaskStatus
的结果进行筛选,包括两种情况:一是job_id
下并非所有任务都完成(即all_done = 0
),二是虽然所有任务已完成,但是至少有一个任务是在今天完成的(通过比较latest_completed_date
与当前日期TRUNC(SYSDATE)
)。 3. 最后,从FilteredTasks
中选择所有列,并按job_id
和to_do_by_date
排序以满足您的要求。
请注意,您需要根据实际的数据库环境调整日期处理逻辑,特别是关于如何确定“今天”的部分,因为不同的数据库系统或版本可能有不同的日期函数和格式。上述代码假设您正在使用的是支持TRUNC函数且日期处理方式符合预期的Oracle版本。