2011-02-24 71 views
0

我需要以下sp的帮助。无法解决它真的。 我有2个表中的列: 1.家长 2.儿童帮助存储过程

我需要创建使用ROWNUM一个SP将创建一个新表与给定参数(水平NUM),将显示之间的连接父母和儿子,或祖父&孙子,等...

例如:

Parent | Child 
2   4 
4   6 

SP将用1给定的级别相同的表返回,但如果我把它2级(祖父< - >孙子)它会显示:

Parent | Child 
2  6 

我该怎么做?

谢谢大家!

回答

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 
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 
+0

我必须使用@@ ROWNUM – Himberjack 2011-02-24 09:41:45

+0

我不明白,你能提供更多的细节? – Branimir 2011-02-24 09:45:37

+0

我需要使用rownum,所以当它0时,我将知道没有更多的孩子可以扫描 - 我可以相当循环 – Himberjack 2011-02-24 09:48:45

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 
+0

我必须使用@@ rownum – Himberjack 2011-02-24 09:42:10

+1

@@ rownum是什么? – 2011-02-24 09:52:02

+0

为什么你需要使用它? – 2011-02-24 13:10:30

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) 

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

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