如何根据[ParentId]从同一个表中选择[ParentName]

时间:2016-03-24 13:11:24

标签: sql sql-server

我有一个像这样的表结构(简化):

Id    ParentId    Name    Desc
------------------------------
1     NULL        A
2     NULL        B
3     1           A1
4     1           A2
5     2           B1

这是一张大桌子,看起来非常痛苦。所以我想创建一个以更好的方式显示数据的视图:

Id    ParentId    ParentName    Name    Desc
--------------------------------------------
1     NULL                      A
3     1           A             A1
4     1           A             A2
2     NULL                      B
5     2           B             B1

我的问题是将ParentName转换为SELECT查询。我显然(尝试过)做不到:

SELECT Id, ParentId, (SELECT Name FROM myTable WHERE Id = ParentId) AS ParentName, Name, Desc FROM myTable INNER JOIN .. WHERE ... GROUP BY etc.

我是否必须采用通用表格表达式(CTE)来完成这项工作?

2 个答案:

答案 0 :(得分:2)

您可以考虑通过简单的ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; 概念来实现,而不是使用CTE

self-join

来自Microsoft的TechNet的Self-Join的更多参考(ref指针记入destination-data

答案 1 :(得分:1)

您的示例只有一个父级别。如果可能有更深的嵌套,您可以使用递归CTE。在这个例子中,我添加了另外两个元素作为子元素下面的子元素:

DECLARE @tbl TABLE(Id INT,ParentId INT, Name VARCHAR(MAX));
INSERT INTO @tbl VALUES
 (1,NULL,'A')
,(2,NULL,'B')
,(3,1,'A1')
,(4,1,'A2')
,(5,2,'B1')
,(6,4,'A2a')
,(7,6,'A2a1')
;

WITH RecursiveCTE AS
(
    SELECT Id,ParentId,Name,Name AS FullPath 
    FROM @tbl AS tbl 
    WHERE ParentId IS NULL

    UNION ALL

    SELECT a.*
          ,derived.FullPath + '/' + a.Name
    FROM RecursiveCTE AS derived 
    CROSS APPLY (SELECT Id,ParentId,Name FROM @tbl AS innerTbl WHERE innerTbl.ParentId=derived.Id) AS a
)
SELECT * FROM RecursiveCTE

结果

Id  ParentId  Name  FullPath
1   NULL      A     A
2   NULL      B     B
5   2         B1    B/B1
3   1         A1    A/A1
4   1         A2    A/A2
6   4         A2a   A/A2/A2a
7   6         A2a1  A/A2/A2a/A2a1