SQL获取所有类别和所有子类别

时间:2017-08-04 08:29:11

标签: sql sql-server sql-server-2008 hierarchical-data recursive-query

你能帮助我获得所有类别的所有类别吗?

enter image description here

数据库创建脚本

CREATE TABLE Category(Id INT NOT NULL, ParentId INT NULL)
GO
INSERT INTO Category (Id, ParentId) VALUES (1, NULL)
INSERT INTO Category (Id, ParentId) VALUES (2, 1)
INSERT INTO Category (Id, ParentId) VALUES (3, 1)
INSERT INTO Category (Id, ParentId) VALUES (4, 2)
INSERT INTO Category (Id, ParentId) VALUES (5, 2)
INSERT INTO Category (Id, ParentId) VALUES (6, 2)
GO

我尝试在ms-sql中使用游标技术和连接方法来解决这个问题但是可以获取所有数据。

SELECT parent.Id AS ParentId, parent.ParentId AS ChildId FROM Category parent
JOIN Category child ON parent.Id = child.Id

期待结果

ParentId    ChildId
----------- -----------
1           1
1           2
1           3
1           4
1           5
1           6
2           2
2           4
2           5
2           6
3           3
4           4
5           5
6           6

谢谢

2 个答案:

答案 0 :(得分:3)

WITH RCTE AS 
(
    SELECT * , Id AS TopLevelParent
    FROM dbo.Category c

    UNION ALL

    SELECT c.* , r.TopLevelParent
    FROM dbo.Category c
    INNER JOIN RCTE r ON c.ParentId = r.Id
)
SELECT 
  r.TopLevelParent AS ParentID
, r.Id AS ChildID 
FROM RCTE r
ORDER BY ParentID;

<强> SQLFiddle DEMO

答案 1 :(得分:1)

正如已经指出的那样,你需要一个递归的CTE。有一件事使得这个有点棘手的事实是你实际上正在将ID(int)转换为字符数据( - )。

我相信以下查询可以帮助您开始获得所需的结果。但是,这并没有考虑到您希望基本上列出所有子项,无论它们在层次结构中的位置如何。

WITH CategoryTree AS
(
    SELECT 
        ID AS CategoryID
        , CAST(ID AS varchar(50)) AS CatVar
        , 0 AS LeafLevel    
        , ParentID
    FROM Category WHERE ParentID IS NULL

    UNION ALL

    SELECT 
        ID AS CategoryID 
        , CAST(CONCAT(CAST(Category.ParentID AS varchar), '-', CAST(Id AS varchar)) AS varchar(50)) AS CatVar
        , CategoryTree.LeafLevel + 1 AS LeafLevel   
        , Category.ParentID
    FROM Category 
        JOIN CategoryTree ON Category.ParentId = CategoryTree.CategoryId
    WHERE Category.ParentID IS NOT NULL
)
SELECT * FROM CategoryTree

输出:

CategoryID  CatVar  LeafLevel   ParentID
1           1       0           NULL
2           1-2     1           1
3           1-3     1           1
4           2-4     2           2
5           2-5     2           2
6           2-6     2           2