用逗号分隔保存父子关系

时间:2015-05-28 14:41:20

标签: sql sql-server

我在SQL 2008 R2中工作

我有一张如下表格

| UID | Value | ParentID    |     Path
|:----|-------|------------:|:------------:|
| 1   |  A    |  NULL       |    |1|       |
| 2   |  B    |  1          |    |1|2|     |
| 3   |  C    |  2          |    |1|2|3|   |
| 4   |  D    |  1          |    |1|4|     |
| 5   |  E    |  NULL       |    |5|       |

插入上面的前3列时,第四列Path应该能够保存与'|'的关系分隔器。如何实现这一目标?

提前致谢。

1 个答案:

答案 0 :(得分:5)

正如D Stanley所提到的,您不希望将Path存储在您的表中。最好只存储UIDValueParentID,然后根据需要查询路径数据。如果您经常需要它,可以考虑为此目的在表上定义视图。执行查询的一种方法是使用recursive CTE。这样的事情应该有效:

-- Sample data from the question.
declare @x table ([UID] bigint, [Value] nchar(1), [ParentID] bigint);
insert @x values 
    (1, N'A', null),
    (2, N'B', 1),
    (3, N'C', 2),
    (4, N'D', 1),
    (5, N'E', null);

with [PathCTE] as
(
    -- Base case: any entry with no parent is its own path.
    select 
        *, 
        [Path] = convert(nvarchar(max), N'|' + convert(nvarchar, [UID]) + N'|')
    from
        @x
    where
        [ParentID] is null

    union all

    -- Recursive case: for any entry whose parent is already in the result set,
    -- we can construct the path by appending a single value to the parent path.
    select
        [Child].*,
        [Path] = convert(nvarchar(max), [Parent].[Path] + convert(nvarchar, [Child].[UID]) + N'|')
    from
        @x [Child]
        inner join [PathCTE] [Parent] on [Child].[ParentID] = [Parent].[UID]
)

select * from [PathCTE] order by [UID];