【问题标题】:Recursively fetching parent ID if reference ID IS NULL如果引用 ID 为 NULL,则递归获取父 ID
【发布时间】:2010-08-15 01:53:45
【问题描述】:

我不确定是应该在代码中执行此操作还是在查询中执行此操作,但我会在这里询问,因为我对自己的 sql 解决方案感兴趣。

假设我有下表,我需要获取 ParentSID1 的所有行。但是,如果这些行中的任何一个返回 Null 作为 FID 那么我还需要去获取 ParentSIDSID FIDNull 的行。

没有限制,它可以继续,并且记录返回的位置可能有 Null 作为 FIDs,我必须找到所有具有其 ParentSID 的行

----------------------
SID    FID    ParentSID

1      null    null          
2      null    null
3      16      1
4      17      1
5      null    1
6      18      5
7      19      2   
----------------------

我在代码中有迭代解决方案,但我必须多次返回数据库才能获得我感兴趣的完整列表,我确信拥有一个 SQL 过程会更有意义,但我不确定如何做吗?

谢谢,

巫毒

【问题讨论】:

  • SQL Server? MySQL?哪个版本?
  • 是否可以有一行 FID = NULL 和 ParentSID != NULL 不链接回 1?如果是这样,也许去规范化是合适的,并且在每行的最终父级中添加 RootParentSID 字段会有所帮助。

标签: sql sql-server tsql sql-server-2008 stored-procedures


【解决方案1】:

我必须使用两个递归 CTE,一个在另一个之上,以获得我相信您期望的输出:

WITH hierarchy AS (
    SELECT *
      FROM dbo.[Table]
     WHERE parentsid = 1
    UNION ALL
    SELECT t.*
      FROM hierarchy h
      JOIN dbo.[Table] t ON h.sid = t.parentsid
                        AND t.fid IS NULL),
     h2 AS (
    SELECT h.*
      FROM hierarchy h
    UNION ALL
    SELECT t.*
      FROM hierarchy h
      JOIN dbo.[Table] t ON h.sid = t.parentsid
                        AND t.fid IS NOT NULL)      
 SELECT *
   FROM h2

第一个获取所有为NULL的;第二个得到fid 不为空的狗腿。

【讨论】:

  • 感谢您回答我的问题并教给我一些我不知道存在的东西 (CTE) - 是否有初学者应该阅读的推荐链接?
  • @VoodooChild:对不起,忘记传递这个链接:4guysfromrolla.com/webtech/071906-1.shtml
【解决方案2】:

Microsoft 让这变得容易多了 - 我相信自 2005 年以来。CTE(通用表表达式)和递归。我可以重复一遍,但 MS 有一个很好的例子......

http://msdn.microsoft.com/en-us/library/ms186243.aspx

【讨论】:

    【解决方案3】:

    我想这是一个经典的问题。您可能希望在这里查看:T-SQL 中的递归。然而,以我的拙见,如果您可以在其他地方(即另一个表中的缓存)展平您的数据结构,然后更轻松地查询,这可能是值得考虑的。由你决定。如果您决定在那里进行循环,搜索各种“递归 T-SQL”应该会引导您找到一些有趣的选项。 FWIW,当我遇到这个时,我只是在代码中完成了它(但我的上下文可能与你的不同)。

    【讨论】:

      【解决方案4】:

      以下查询为您提供预期结果。 选择 * 从 @表一 其中 ParentSID=1 或 ParentSID IN(从 @表一 其中 ParentSID=1 且 FID 为 NULL)

      我已经举例说明了这一点

      示例

      declare @table table ([SID] int, FID int, ParentSID int)
      
      insert into @table Values(1, null, null)
      insert into @table Values(2, null, null)
      insert into @table Values(3, 16, 1)
      insert into @table Values(4, 17, 1)
      insert into @table Values(5, null, 1)
      insert into @table Values(6, 18, 5)
      insert into @table Values(7, null, 1)
      insert into @table Values(8, 19, 7)
      
      select * from 
          @table A
      where ParentSID=1 OR
      ParentSID IN (select SID from 
          @table A
      where ParentSID=1 AND FID is NULL)
      

      【讨论】:

        【解决方案5】:

        这很简单:

        if(not exists(select  * 
                      from    table 
                      where   FID is null
                              and
                              ParentSID = 1)  )
        
            select 
                * 
            from 
                table
            where 
                ParentSID = 1
        else
            select 
                * 
            from 
                table
            where
                ParentSID = SID 
        

        【讨论】:

          猜你喜欢
          • 2020-03-22
          • 1970-01-01
          • 2022-06-14
          • 2016-12-03
          • 2013-08-13
          • 2012-09-18
          • 2020-07-25
          • 2020-02-17
          • 2011-04-12
          相关资源
          最近更新 更多