帮助商店程序

时间:2011-02-24 08:51:00

标签: sql-server stored-procedures

我需要以下sp的帮助。真的无法解决它。 我在表中有2列: 1.家长 2.孩子

我需要使用rownum创建一个sp,它将创建一个具有给定param(级别num)的新表,该param将显示父和子之间的连接,或祖父&孙子等...

例如:

Parent | Child
2         4
4         6

sp将返回给定级别为1的同一个表,但是如果我将它交给2级(祖父< - >孙子),它将显示:

Parent | Child
2        6

我该怎么做?

全部谢谢!

4 个答案:

答案 0 :(得分:1)

这是一些使用递归cte的代码,它可以完成我认为你想要的东西。

-- Sample data
declare @T table (ID int, ParentID int)
insert into @T values
(1, null),
  (2, 1),
  (3, 1),
    (4, 3),
    (5, 3),
  (6, 1),
(7, null),
  (8, 7),
    (9, 8),
      (10, 9)

-- The level you want
declare @Level int = 2

-- recursive cte
;with cte as
(
  select
    ID,
    ParentID,
    0 as lvl
  from @T
  where ParentID is null
  union all
  select
    T.ID,
    T.ParentID,
    C.lvl+1 as lvl
  from @T as T
    inner join cte as C
      on T.ParentID = C.ID
  where C.lvl < @Level    
)
select *
from cte
where lvl = @Level

答案 1 :(得分:0)

您可以使用自动加入。对于第2级:

SELECT  
    p.Parent
    ,c.Child
FROM 
    Table_1 p
JOIN Table_1 c 
    ON p.Child = c.Parent

等级3:

SELECT 
    g.Parent
    ,c.Child
FROM 
    Table_1 g
JOIN Table_1 p
    ON g.Child = p.Parent
JOIN Table_1 c 
    ON p.Child = c.Parent

如果您需要任意级别的解决方案,请尝试根据级别生成dinamic sql

CREATE PROCEDURE GetConnected
    @level INT
AS
BEGIN
    DECLARE @sql VARCHAR(1000)

    SET @sql = 'SELECT t0.Parent, t' + CAST(@level AS VARCHAR(5)) + '.Child FROM Table_1 t0 '

    DECLARE @counter INT
    SET @counter = 0

    WHILE @counter < @level
    BEGIN   
        SET @sql = @sql + 'JOIN Table_1 t' + CAST(@counter + 1 AS VARCHAR(5)) + ' ON t' + CAST(@counter AS VARCHAR(5)) + '.Child = t' + CAST(@counter + 1 AS VARCHAR(5)) + '.Parent '
        SET @counter = @counter + 1
    END

    EXEC (@sql)
END

答案 2 :(得分:0)

DECLARE     @level INT
SET         @level = 3

DECLARE @temp TABLE 
(
  parent    INT, 
  child     INT
)

DECLARE @result TABLE
(
  parent    INT, 
  child     INT
)

INSERT INTO     @result
SELECT * FROM   testing

WHILE @level > 1
BEGIN
    SET @level = @level - 1
    DELETE  @temp

    INSERT INTO @temp
    SELECT t.parent, r.child
    FROM testing t
    INNER JOIN @result r
        ON t.child = r.parent

    DELETE @result

    INSERT INTO @result
    SELECT * FROM @temp
END

SELECT * FROM @result

答案 3 :(得分:0)

这个解决方案,我无耻地借用了Mikael的样本数据定义,显示了所代表的所有关系,不仅从顶级(无父)项目构建对,而且从较低级别的项目构建对。该问题的作者没有说明它应该是一种方式还是另一种方式。

/* Sample data */
DECLARE @T TABLE (ID int, ParentID int);
INSERT INTO @T VALUES
(1, NULL),
  (2, 1),
  (3, 1),
    (4, 3),
    (5, 3),
  (6, 1),
(7, NULL),
  (8, 7),
    (9, 8),
      (10, 9);

/* The level you want */
DECLARE @Level int;
SET @Level = 2;

/* The query */
WITH recur AS (
  SELECT
    ID,
    AncestorID = ParentID,
    Level = CASE WHEN ParentID IS NULL THEN 0 ELSE 1 END
  FROM @T
  UNION ALL
  SELECT
    r.ID,
    t.AncestorID,
    Level = r.Level + 1
  FROM @T t
    INNER JOIN recur r ON t.ID = r.AncestorID
  WHERE r.Level < @Level
)
SELECT ID, ParentID
FROM recur
WHERE Level = @Level
  AND (@Level = 0 OR ParentID IS NOT NULL)

对于@Level的给定2值,结果将为:

ID          AncestorID  Level
----------- ----------- -----------
10          8           2
9           7           2
5           1           2
4           1           2