选择路径(多个记录),其中表中的ID号(fk)引用同一表中的另一个ID号(pk)

时间:2017-02-23 17:52:28

标签: sql sql-server sql-server-2008

我有一个带有ID号的表,它引用了旧的ID号(外键引用了同一个表中的主键)。我遇到的问题是有一些未知数量的记录需要循环才能返回到原始的RecordID。例如,数据可能如下所示:

CategoryID | CategoryName | ParentCategory
-----------+--------------+---------------
1          | Books        | NULL
2          | Music        | NULL
3          | Hardcover    | 1
4          | Softcover    | 1
5          | Electronic   | 1
6          | CD           | 2
7          | MP3          | 2
8          | Rock         | 6
9          | Hard Rock    | 6
10         | Classic Rock | 6
11         | Fiction      | 3
12         | Fiction      | 4
13         | Non-Fiction  | 3
14         | Reference    | 13
15         | Biography    | 13

所以,我的结果集必须是:

Column A  |   Column B   |  Column C
----------+--------------+-------------
1         | Books        | [NULL]
2         | Music        | [NULL]
3         | Hardcover    | [Books]
4         | Softcover    | [Books]
5         | Electronic   | [Books]
6         | CD           | [Music]
7         | MP3          | [Music]
8         | Rock         | [CD, Music]
9         | Hard Rock    | [Rock, CD, Music]
10        | Classic Rock | [Rock, CD, Music]
11        | Fiction      | [Softcover, Books]
12        | Fiction      | [Hardcover, Books]
13        | Non-Fiction  | [Hardcover, Books]
14        | Reference    | [Non-Fiction, Hardcover, Books]
15        | Biography    | [Non-Fiction, Hardcover, Books]

......你明白了。我可以有无限数量的类别来循环,需要显示一个返回第一个记录的路径,返回空值。

我知道我需要某种情况和循环,如果存在,那么选择它,如果存在然后选择next并且可能将它映射到XML路径但是我真的很难用语法和逻辑来实现这一点发生。谢谢!

1 个答案:

答案 0 :(得分:0)

使用像这样的邻接列表列表时,通常需要使用这样的递归common table expressions

;with cte as (
select
    t.*
  , Path = convert(varchar(128),CategoryName)
  , ParentPath = convert(varchar(128),null)
from t
where t.ParentCategory is null
union all 
select 
    c.*
  , [Path] = convert(varchar(128),p.Path + ', ' + c.CategoryName)
  , ParentPath = p.Path
  from t as c
    inner join cte p 
      on c.ParentCategory = p.CategoryID
    )
select 
    CategoryId
  , CategoryName
  , Path=quotename(ParentPath)
from cte
order by CategoryId

测试设置:http://rextester.com/SSWK51498

返回:

+------------+--------------+---------------------------------+
| CategoryId | CategoryName |              Path               |
+------------+--------------+---------------------------------+
|          1 | Books        | NULL                            |
|          2 | Music        | NULL                            |
|          3 | Hardcover    | [Books]                         |
|          4 | Softcover    | [Books]                         |
|          5 | Electronic   | [Books]                         |
|          6 | CD           | [Music]                         |
|          7 | MP3          | [Music]                         |
|          8 | Rock         | [Music, CD]                     |
|          9 | Hard Rock    | [Music, CD]                     |
|         10 | Classic Rock | [Music, CD]                     |
|         11 | Fiction      | [Books, Hardcover]              |
|         12 | Fiction      | [Books, Softcover]              |
|         13 | Non-Fiction  | [Books, Hardcover]              |
|         14 | Reference    | [Books, Hardcover, Non-Fiction] |
|         15 | Biography    | [Books, Hardcover, Non-Fiction] |
+------------+--------------+---------------------------------+

参考文献: