2011-01-07 78 views
2

我創造了各種各樣的狀態圖與數據存儲在一個簡單的自我引用表(JobPath)遞歸查詢的自我參照表(未分級)

JobId - ParentJobId 

我使用的是標準的SQL CTE用以下數據得到哪些直到我結束了在正常使用的數據現在

JobId - ParentId 
    1  2 
    2  3 
    3  4 
    4  2 

,你可以看到工作4個鏈接招聘2都到招聘3,然後到作業4等。

有沒有什麼辦法可以告訴我的查詢不要提取已有的數據?


這裏是我當前的查詢

WITH JobPathTemp (JobId, ParentId, Level) 
AS 
(
-- Anchor member definition 
    SELECT j.JobId, jp.ParentJobId, 1 AS Level 
    FROM Job AS j 
    LEFT OUTER JOIN dbo.JobPath AS jp 
     ON j.JobId = jp.JobId 
    where j.JobId=1516 
    UNION ALL 
-- Recursive member definition 
    SELECT j.JobId, jp.ParentJobId, Level + 1 
    FROM dbo.Job as j 
    INNER JOIN dbo.JobPath AS jp 
     ON j.JobId = jp.JobId 
    INNER JOIN JobPathTemp AS jpt 
     ON jpt.ParentId = jp.JobId 
     WHERE jp.ParentJobId <> jpt.JobId 
) 

- 語句執行的CTE

SELECT * FROM JobPathTemp 
+0

你的查詢是什麼樣的?你不能使用Distinct? – Kell 2011-01-07 11:00:01

+0

「遞歸公用表表達式'JobPathTemp'的遞歸部分不允許使用DISTINCT運算符。」 – 2011-01-07 11:33:00

回答

3

如果你是沒有處理大量的條目,下面的解決方案可能是合適的。這個想法是爲每一行建立完整的「id路徑」,並確保「當前id」(在遞歸部分中)不在正在處理的路徑中:

(我將連接移除到jobpath以進行測試目的,但基本模式應該是相同的)

 
WITH JobPathTemp (JobId, ParentId, Level, id_path) 
AS 
(
    SELECT jobid, 
     parentid, 
     1 as level, 
     '|' + cast(jobid as varchar(max)) as id_path 
    FROM job 
    WHERE jobid = 1 

    UNION ALL 

    SELECT j.JobId, 
      j.parentid, 
      Level + 1, 
      jpt.id_path + '|' + cast(j.jobid as varchar(max)) 
    FROM Job as j 
    INNER JOIN JobPathTemp AS jpt ON j.jobid = jpt.parentid 
            AND charindex('|' + cast(j.jobid as varchar), jpt.id_path) = 0 
) 
SELECT * 
FROM JobPathTemp 
; 
0

此解決方案不起作用,SQL Server不使用UNION加盟支持一起遞歸術語。既然你不能指遞歸除了作爲連接,TBH我看不出有任何的替代使用存儲功能...


你不發表您的查詢...但我嘗試(在Postgres的,這在幾乎相同的方式工作),如果你在遞歸長期使用「聯盟」(而不是「UNION ALL」),那麼它應該自動刪除重複的行:

with /*recursive*/ jobs as 
(select jobpath.jobid, jobpath.parentjobid from jobpath where jobid = 1 
    union 
    select jobpath.jobid, jobpath.parentjobid 
    from jobpath 
     join jobs on jobs.parentjobid = jobpath.jobid 
) 
select jobpath.* from jobpath join jobs on jobpath.jobid = jobs.jobid; 
+0

現在我添加了我的查詢,當我更改爲僅聯盟時我得到這個 「遞歸公用表表達式'JobPathTemp'不包含頂級UNION ALL運算符。」 – 2011-01-07 11:34:25