【问题标题】:Recursion in Select Statement for SQL ServerSQL Server 的 Select 语句中的递归
【发布时间】:2016-10-30 19:58:31
【问题描述】:

我有三个 SQL Server 表:ProjectsProjectTreeProjectTreeRec

Projects 类似于目录,我试图在名为Standard Parts 的目录下查找所有子目录。显然这里需要递归。

Projects 表具有以下列:

ProjectID, Name, Deleted

ProjectTree 表具有以下列:

ProjectID, ChildProject

我认为我不需要ProjectTreeRec 表作为这项工作的一部分,但它包含ChildProjectIDParentProjectIDLevel 列。

我想开发一个递归选择语句来查找Standard Parts目录下所有未被删除的子目录(不是1,而是0)。

我是 CTE 和递归的新手。我得到了一些结果,但不是我所追求的。

这是非递归调用,它找到了我的第一级,但没有更深入。它工作正常。

SELECT 
    '(Directory Not Available)'

UNION

SELECT DISTINCT
    C.[Name] 
FROM 
    [EPDM].[dbo].[Projects] A
JOIN 
    [EPDM].[dbo].[ProjectTree] B ON B.ProjectID = A.ProjectID 
JOIN 
    [EPDM].[dbo].[Projects] C ON B.childproject = C.projectid 
WHERE
    A.name = 'Standard Part Library' 
    AND A.[Deleted] = 0;

欢迎任何帮助。

【问题讨论】:

  • 您使用的是哪个版本的 SQL Server?
  • 你可以检查它的递归 CTE:stackoverflow.com/questions/37973842/…
  • 我使用的是 SQL Server Standard 2014。
  • SELECT SUBSTRING([Path], 0, (LEN([Path]) )) as [Path] FROM ( SELECT -- 将标准部分字符串替换为空白,然后从中替换 '\'空白 REPLACE([Path], '\03-Standard Parts\', '') as [Path] FROM Projects Where [Path] Like '%Standard Parts%' and Deleted = 0 ) as x
  • 旁注:我建议养成使用更具表现力、更有意义表别名的习惯,而不仅仅是ab ..... p for Projectspt for ProjectTreep2 for Projects(第二次出现)对于查看您的代码的人来说会更直观跨度>

标签: sql sql-server tsql recursion sql-server-2014


【解决方案1】:

我会尝试以下类似的方法来评估树结构,然后将 cte 加入您的表以获得名称:

DECLARE @SearchProjectID int = 1;

WITH cteTree AS(
SELECT ProjectID, ChildProject
  FROM ProjectTree
  WHERE ProjectID = @SearchProjectID
UNION ALL
SELECT pt.ProjectID, pt.ChildProject
  FROM ProjectTree AS pt
  JOIN cteTree AS ct ON ct.ChildProject = pt.ProjectID
)
SELECT *
  FROM cteTree

【讨论】:

    【解决方案2】:

    请试试这个...

      CREATE TABLE #Project
    (
    ProjectID INT 
    ,Name varchar(50)
    ,Deleted bit
    )
    
    CREATE TABLE #ProjectTree
    (
    ProjectID INT, 
    ChildProject INT
    )
    
    INSERT INTO #Project
    (ProjectID,Name,Deleted)
    SELECT 1,'Standard Part Library',0
    UNION ALL SELECT 2,'P2',1
    UNION ALL SELECT 3,'P3',0
    UNION ALL SELECT 4,'P4',0
    
    INSERT INTO #ProjectTree
    (ProjectID,ChildProject)
    SELECT 1,3
    UNION SELECT 2,4
    
    SELECT * FROM #Project
    SELECT * FROM #ProjectTree
    
    ;WITH CTE_Project 
    AS
    (
    SELECT 
    	A.ProjectId
    	,B.ChildProject
    	,A.Name AS ProjectName
    FROM #Project A
    	INNER JOIN #ProjectTree B
    		ON A.ProjectId = B.ProjectId
    WHERE
    	A.Name = 'Standard Part Library' 
    	AND A.[Deleted] = 0
    
    UNION ALL
    
    SELECT 
    	PT.ProjectID
    	,PT.ChildProject
    	,CP.ProjectName AS ProjectName
    FROM 
    	#ProjectTree AS PT
    	INNER JOIN CTE_Project CP 
    		ON PT.ChildProject = CP.ProjectID
    )
    SELECT 
    ProjectName
    ,ProjectId
    ,ChildProject
    FROM 
    CTE_Project;

    【讨论】:

    • 这会运行,但不会返回标准零件下的目录 - P2、P3、P4。关闭但不完全在那里。
    猜你喜欢
    • 2013-07-06
    • 2015-10-30
    • 2017-03-11
    • 2012-05-18
    • 2013-02-17
    • 2012-06-28
    • 2017-07-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多