有没有办法在 SQL Server 2008 R2 中避免这个循环?
Is there a way to avoid this loop in SQL Server 2008 R2?
我经常看到专家用户建议尽量避免数据库级别的循环(参考 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
代码解释:
我有一个 table,其中有任务,有些行是其他任务的更新,所以我有一列是下一个版本的 ID。我想要的是找到一个任务的最后一个版本的id
。
编辑:
表格结构
CREATE TABLE task
(
id_task INT IDENTITY(1,1) NOT NULL,
task NVARCHAR(50) NULL,
id_next_version INT NULL
)
您正在遍历一个图——实际上可能是一个树结构。您可以使用递归 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 Fiddle 说明代码。
我经常看到专家用户建议尽量避免数据库级别的循环(参考 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
代码解释:
我有一个 table,其中有任务,有些行是其他任务的更新,所以我有一列是下一个版本的 ID。我想要的是找到一个任务的最后一个版本的id
。
编辑:
表格结构
CREATE TABLE task
(
id_task INT IDENTITY(1,1) NOT NULL,
task NVARCHAR(50) NULL,
id_next_version INT NULL
)
您正在遍历一个图——实际上可能是一个树结构。您可以使用递归 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 Fiddle 说明代码。