SQL递归菜单排序

And*_*nna 1 sql-server-2005 sql-server-2008

我有一个简单的表,我用它来表示类别的层次结构.

CREATE TABLE [dbo].[Categories](
    [ID] [int] IDENTITY(1,1) NOT NULL,
[Title] [varchar](256) NOT NULL,
[ParentID] [int] NOT NULL,
CONSTRAINT [PK_Categories] PRIMARY KEY CLUSTERED 
(
[ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

INSERT INTO [MDS].[dbo].[Categories]([Title],[ParentID]) VALUES ('All', 0)
INSERT INTO [MDS].[dbo].[Categories]([Title],[ParentID]) VALUES ('Banking', 8)
INSERT INTO [MDS].[dbo].[Categories]([Title],[ParentID]) VALUES ('USAA Checking', 2)
INSERT INTO [MDS].[dbo].[Categories]([Title],[ParentID]) VALUES ('USAA Mastercard', 2)
INSERT INTO [MDS].[dbo].[Categories]([Title],[ParentID]) VALUES ('Medical', 8)
INSERT INTO [MDS].[dbo].[Categories]([Title],[ParentID]) VALUES ('Jobs', 8)
INSERT INTO [MDS].[dbo].[Categories]([Title],[ParentID]) VALUES ('Archive', 1)
INSERT INTO [MDS].[dbo].[Categories]([Title],[ParentID]) VALUES ('Active', 1)
INSERT INTO [MDS].[dbo].[Categories]([Title],[ParentID]) VALUES ('BoA Amex', 2)
Run Code Online (Sandbox Code Playgroud)

除了选择整棵树之外,一切都很好.这是我的查询,我删除了我的ORDER BY因为它不起作用:

WITH CategoryTree (ID, Title, Level, ParentID) AS
(
   SELECT  r.ID, r.Title, 0 Level, r.ParentID
   FROM Categories r
   WHERE r.ParentID = 0

   UNION ALL

   SELECT c.ID, c.Title, p.Level + 1 AS Level, c.ParentID
   FROM Categories c
   INNER JOIN CategoryTree p
      ON p.ID = c.ParentID
)

SELECT  ID,
    REPLICATE('-----', Level) + Title AS Title,
    ParentID
FROM CategoryTree
Run Code Online (Sandbox Code Playgroud)

结果:

ID  Title                        ParentID
1   All                              0
7   -----Archive                     1
8   -----Active                      1
2   ----------Banking                8
5   ----------Medical                8
6   ----------Jobs                   8
3   ---------------USAA Checking     2
4   ---------------USAA Mastercard   2
9   ---------------BoA Amex          2
Run Code Online (Sandbox Code Playgroud)

我想要的结果是:

ID  Title                            ParentID
1   All                               0
8   -----Active                      1
2   ----------Banking                8
9   ---------------BoA Amex          2
3   ---------------USAA Checking     2
4   ---------------USAA Mastercard   2
6   ----------Jobs                   8
5   ----------Medical                8
7   -----Archive                     1
Run Code Online (Sandbox Code Playgroud)

杀死我的是我之前完成了这项工作,但后来忘记备份数据库并在服务器升级中丢失了.

我在2008年查看了HierarchyID类型,但如果你关心同一级别的孩子的顺序,它似乎是一个很大的痛苦.

Dam*_*vic 6

好的,得到它:) - 这似乎在这里工作.

DECLARE @Categories TABLE (
 ID int PRIMARY KEY
,Title varchar(256)
,ParentID int
)

INSERT INTO @Categories
VALUES
 (1, 'All', 0)
,(2,'Banking', 8)
,(3,'USAA Checking', 2)
,(4,'USAA Mastercard', 2)
,(5,'Medical', 8)
,(6,'Jobs', 8)
,(7,'Archive', 1)
,(8,'Active', 1)
,(9,'BoA Amex', 2)


;
WITH  CategoryTree
        AS (SELECT  r.ID, r.Title, 0 Level, r.ParentID,
                    CAST(r.Title AS VARCHAR(1000)) AS "Path"
            FROM    @Categories r
            WHERE   r.ParentID = 0
            UNION ALL
            SELECT  c.ID, c.Title, p.Level + 1 AS Level, c.ParentID,
                    CAST((p.path + '/' + c.Title) AS VARCHAR(1000)) AS "Path"
            FROM    @Categories c
                    INNER JOIN CategoryTree p
                      ON p.ID = c.ParentID
           )
  SELECT  ID, REPLICATE('-----', Level) + Title AS Title, [Path]
  FROM    CategoryTree
  ORDER BY [Path]
Run Code Online (Sandbox Code Playgroud)