描述:1767.寻找没有被执行的任务对
表:
Tasks
+----------------+---------+ | Column Name | Type | +----------------+---------+ | task_id | int | | subtasks_count | int | +----------------+---------+ task_id 具有唯一值的列。 task_id 表示的为主任务的id,每一个task_id被分为了多个子任务(subtasks),subtasks_count表示为子任务的个数(n),它的值表示了子任务的索引从1到n。 本表保证2 <=subtasks_count<= 20。表:
Executed
+---------------+---------+ | Column Name | Type | +---------------+---------+ | task_id | int | | subtask_id | int | +---------------+---------+ (task_id, subtask_id) 是该表中具有唯一值的列的组合。 每一行表示标记为task_id的主任务与标记为subtask_id的子任务被成功执行。 本表 保证 ,对于每一个task_id,subtask_id <= subtasks_count。编写解决方案报告没有被执行的(主任务,子任务)对,即没有被执行的(task_id, subtask_id)。
以 任何顺序 返回即可。
查询结果格式如下。
示例 1:
输入: Tasks 表: +---------+----------------+ | task_id | subtasks_count | +---------+----------------+ | 1 | 3 | | 2 | 2 | | 3 | 4 | +---------+----------------+ Executed 表: +---------+------------+ | task_id | subtask_id | +---------+------------+ | 1 | 2 | | 3 | 1 | | 3 | 2 | | 3 | 3 | | 3 | 4 | +---------+------------+ 输出: +---------+------------+ | task_id | subtask_id | +---------+------------+ | 1 | 1 | | 1 | 3 | | 2 | 1 | | 2 | 2 | +---------+------------+ 解释: Task 1 被分成了 3 subtasks (1, 2, 3)。只有 subtask 2 被成功执行, 所以我们返回 (1, 1) 和 (1, 3) 这两个主任务子任务对。 Task 2 被分成了 2 subtasks (1, 2)。没有一个subtask被成功执行, 因此我们返回(2, 1)和(2, 2)。 Task 3 被分成了 4 subtasks (1, 2, 3, 4)。所有的subtask都被成功执行,因此对于Task 3,我们不返回任何值。
数据准备:
Create table If Not Exists Tasks (task_id int, subtasks_count int)
Create table If Not Exists Executed (task_id int, subtask_id int)
Truncate table Tasks
insert into Tasks (task_id, subtasks_count) values ('1', '3')
insert into Tasks (task_id, subtasks_count) values ('2', '2')
insert into Tasks (task_id, subtasks_count) values ('3', '4')
Truncate table Executed
insert into Executed (task_id, subtask_id) values ('1', '2')
insert into Executed (task_id, subtask_id) values ('3', '1')
insert into Executed (task_id, subtask_id) values ('3', '2')
insert into Executed (task_id, subtask_id) values ('3', '3')
insert into Executed (task_id, subtask_id) values ('3', '4')
分析:
①准备知识 首先先学习一个循环recursive
构造一个 1 - 10 的列表
(先将1作为number列的值 连接 每一个 number+1 直到number值为10)
with recursive number_series as (select 1 as numberunion all select number+1 as numberfrom number_serieswhere number < 10 ) select * from number_series;②根据上述知识构造出所有的任务对
(从tasks表中取出任务id 和 任务总数 连接循环的任务id 和 任务总数-1 --> 任务编号 直到 任务编号为1 , 就是将任务总数 依次减一 扩散出它的所有任务编号)
with recursive subtasks as(select task_id,subtasks_count as sub_id from Tasksunion allselect task_id,sub_id-1from subtaskswhere sub_id > 1 ) select subtasks.task_id,sub_id from subtasks③将此表与Executed表进行左连接 过滤出executed表中为空的那行任务对
with recursive subtasks as(select task_id,subtasks_count as sub_id from Tasksunion allselect task_id,sub_id-1from subtaskswhere sub_id > 1 ) select subtasks.task_id,sub_id subtask_id from subtasks left join Executed on Executed.task_id = subtasks.task_id and Executed.subtask_id = subtasks.sub_id where Executed.subtask_id is null;
代码:
with recursive subtasks as(select task_id,subtasks_count as sub_id from Tasksunion allselect task_id,sub_id-1from subtaskswhere sub_id > 1
)
select subtasks.task_id,sub_id subtask_id from subtasks left join Executed
on Executed.task_id = subtasks.task_id and Executed.subtask_id = subtasks.sub_id
where Executed.subtask_id is null;
总结:
掌握 用recursive循环 构造数列
先用1作为起点
再将一个值作为where 终点 此处来源表为recursive后的表