FIX MYSQL 更新内部联接和按查询排序并设置变量
FIX MYSQL UPDATE INNER JOIN and ORDER BY QUERY and SET VARIABLE
我有 2 个 MYSQL 表:持续时间和任务。
CREATE TABLE `durations` (
`task_type` varchar(10) NOT NULL,
`seconds` int(11) NOT NULL
) ENGINE=InnoDB ;
CREATE TABLE `tasks` (
`id` int(11) NOT NULL,
`task_type` varchar(10) NOT NULL,
`const` int(11) NOT NULL,
`timestamp` int(11) NOT NULL,
`status` int(11) NOT NULL,
`tempCol` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB ;
task_type seconds
type1 3
type2 5
id task_type const timestamp status tempCol
1 type1 1 10 0 0
2 type1 2 3 0 0
3 type1 3 12 0 0
4 type1 4 5 0 0
我有一个总时间值:例如 15 秒。从这个值开始,只有在 total_time - tasks.const*durations.seconds 是 > 0。如果连续更新,total_time 减少 tasks.const*durations.seconds 以用于下一行。
我有 运行 以下查询:
SET @tempVariable = 15;
UPDATE tasks
INNER JOIN durations ON tasks.task_type=durations.task_type
SET status=1, tasks.tempCol = (@tempVariable:=@tempVariable-tasks.const*durations.seconds)
WHERE @tempVariable-tasks.const*durations.seconds > 0
ORDER BY tasks.timestamp ASC
我创建了 tempCol,以便可以在每一行中更新 @tempVariable。
由于 UPDATE 和 ORDER BY 的不正确使用,此查询不起作用。如果我省略 order by 子句,查询工作正常,但是,我需要按时间戳 ASC 更新值 ORDER。
有任何修复查询的建议吗?
谢谢。
已编辑。
我基于 GMB 解决方案的最终查询是:
SET @tempVariable = 15;
update tasks t
inner join (
select t.id, (t.const * d.seconds) workload
from tasks t
inner join durations d on d.task_type = t.task_type
order by t.`timestamp` asc
) t1 on t1.id = t.id
set t.status = 1, t.tempCol=(@tempVariable:=@tempVariable-t1.workload)
where @tempVariable-t1.workload >= 0
如果你是 运行 MySQL 8.0,你可以用 window 函数来做到这一点:
update tasks t
inner join (
select t.id, sum(t.const * d.second) over(order by t.id) total_duration
from tasks t
inner join duration d on d.task_type = t.task_type
) t1 on t1.id = t.id
set t.status = 1
where t1.total_duration <= 15
在早期版本中,我会使用相关子查询而不是变量:
update tasks t
inner join (
select t.id,
(select sum(t1.const * d.second) from tasks t1 where t1.id <= t.id) total_duration
from tasks t
inner join duration d on d.task_type = t.task_type
) t1 on t1.id = t.id
set t.status = 1
where t1.total_duration <) 15
我有 2 个 MYSQL 表:持续时间和任务。
CREATE TABLE `durations` (
`task_type` varchar(10) NOT NULL,
`seconds` int(11) NOT NULL
) ENGINE=InnoDB ;
CREATE TABLE `tasks` (
`id` int(11) NOT NULL,
`task_type` varchar(10) NOT NULL,
`const` int(11) NOT NULL,
`timestamp` int(11) NOT NULL,
`status` int(11) NOT NULL,
`tempCol` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB ;
task_type seconds
type1 3
type2 5
id task_type const timestamp status tempCol
1 type1 1 10 0 0
2 type1 2 3 0 0
3 type1 3 12 0 0
4 type1 4 5 0 0
我有一个总时间值:例如 15 秒。从这个值开始,只有在 total_time - tasks.const*durations.seconds 是 > 0。如果连续更新,total_time 减少 tasks.const*durations.seconds 以用于下一行。 我有 运行 以下查询:
SET @tempVariable = 15;
UPDATE tasks
INNER JOIN durations ON tasks.task_type=durations.task_type
SET status=1, tasks.tempCol = (@tempVariable:=@tempVariable-tasks.const*durations.seconds)
WHERE @tempVariable-tasks.const*durations.seconds > 0
ORDER BY tasks.timestamp ASC
我创建了 tempCol,以便可以在每一行中更新 @tempVariable。 由于 UPDATE 和 ORDER BY 的不正确使用,此查询不起作用。如果我省略 order by 子句,查询工作正常,但是,我需要按时间戳 ASC 更新值 ORDER。
有任何修复查询的建议吗?
谢谢。
已编辑。 我基于 GMB 解决方案的最终查询是:
SET @tempVariable = 15;
update tasks t
inner join (
select t.id, (t.const * d.seconds) workload
from tasks t
inner join durations d on d.task_type = t.task_type
order by t.`timestamp` asc
) t1 on t1.id = t.id
set t.status = 1, t.tempCol=(@tempVariable:=@tempVariable-t1.workload)
where @tempVariable-t1.workload >= 0
如果你是 运行 MySQL 8.0,你可以用 window 函数来做到这一点:
update tasks t
inner join (
select t.id, sum(t.const * d.second) over(order by t.id) total_duration
from tasks t
inner join duration d on d.task_type = t.task_type
) t1 on t1.id = t.id
set t.status = 1
where t1.total_duration <= 15
在早期版本中,我会使用相关子查询而不是变量:
update tasks t
inner join (
select t.id,
(select sum(t1.const * d.second) from tasks t1 where t1.id <= t.id) total_duration
from tasks t
inner join duration d on d.task_type = t.task_type
) t1 on t1.id = t.id
set t.status = 1
where t1.total_duration <) 15