我经常看到专家用户建议在数据库级别尝试避免循环(参考here)。我有一个简短的代码块,我无法在不使用循环的情况下看到其他方法来实现任务。任务很简单,但有没有办法避免循环?
DECLARE @id INT = 1
DECLARE @auxId INT
WHILE @id IS NOT NULL
BEGIN
SET @auxId = @id
SELECT @id = id_next_version FROM task WHERE id_task = @id
END
SELECT @aux
代码说明:
我有一个表有任务,有些行是其他任务的更新,所以我有一个列,其中是下一个版本的id。我想要的是找到任务的最后一个版本的id
。
编辑:
表格结构
CREATE TABLE task
(
id_task INT IDENTITY(1,1) NOT NULL,
task NVARCHAR(50) NULL,
id_next_version INT NULL
)
答案 0 :(得分:4)
您正在遍历图表 - 实际上可能是树结构。您可以使用递归CTE执行此操作:
with cte as (
select id_task, id_next_version, 1 as lev
from task
where id_task = @id
union all
select t.id_task, t.id_next_version, cte.lev + 1
from task t join
cte
on t.id_task = cte.id_next_version
)
select top 1 *
from cte
order by lev desc;
我不确定这比你的循环更优雅。它应该更快,因为你只传递一个查询。
Here是一个说明代码的SQL小提琴。