我正在创建一个状态图表,数据存储在一个简单的自引用表(JobPath)中
JobId - ParentJobId
我使用标准的SQL CTE来获取数据,这些数据一直运行良好,直到我得到以下数据
JobId - ParentId
1 2
2 3
3 4
4 2
现在您可以看到作业2的作业4链接到作业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 :(得分: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 ;
答案 1 :(得分:0)
此解决方案不起作用,SQL Server不支持使用UNION将递归术语连接在一起。既然你不能引用递归,除了作为连接,tbh我没有看到使用存储函数的任何替代...
您没有发布您的查询...但我尝试过(在postgres中,它以相同的方式工作)如果您在递归术语中使用“UNION”(而不是“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;