如果引用ID为IS NULL,则递归获取父ID

时间:2010-08-15 01:53:46

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

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

如果我有下表,我需要获取 ParentSID 1 的所有行。但是,如果这些行中的任何行返回 Null FID ,那么我还需要获取 ParentSID SID <的所有行/ strong> FID Null 的行。

没有任何限制,它可以继续记录返回的位置 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过程会更有意义,但我不知道如何做到了吗?

谢谢,

巫毒

5 个答案:

答案 0 :(得分:2)

我不得不使用两个递归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不为空的狗腿。

答案 1 :(得分:2)

微软已经让这更容易了 - 我相信自2005年以来.CTE(常用表表达式)和递归。我可以重复一下,但MS有一个很好的例子......

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

答案 2 :(得分:1)

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

答案 3 :(得分:1)

以下查询为您提供了预期的内容。     选择*来自         @table A.     其中ParentSID = 1 OR     ParentSID IN(从中选择SID)         @table A.     其中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)

答案 4 :(得分:0)

这很简单:

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