2015-01-07 2 views
2

필자는 종종 전문가 수준의 사용자가 데이터베이스 수준에서 루프를 피하는 것이 좋습니다 (참조 here). 루프의 사용없이 작업을 수행하는 다른 방법을 볼 수없는 짧은 코드 블록이 있습니다. 작업은 매우 간단하지만 루프를 피할 수있는 방법이 있습니까? 코드의SQL Server 2008 R2에서이 루프를 피할 수있는 방법이 있습니까?

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 
) 

답변

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 Fiddle입니다.

+0

방금 ​​코드를 실행했지만 아무 것도 반환하지 않습니다. 어떤 힌트? – smartdan

+0

@DanielGonzalez. . . SQL Fiddle과 SQL Server의 로컬 인스턴스에 대한 예제 데이터에서 모두 작동합니다. –

+0

내 경험상 이것은 훨씬 더 빠른 이오타 일 수 있습니다. 이것은 기본적으로 루프를 루프 조인으로 이동합니다. 그 루프의 훨씬 더 단단한 몸. – usr

관련 문제