2009-11-19 153 views
1

我有一張簡單的表格,用來表示類別層次結構。SQL遞歸菜單排序

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) 

除了選擇整個樹以外,一切都很好。這裏是我的查詢,我刪除了我的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 

結果:

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 

我想結果是這樣的:

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 

什麼是殺害我是我以前完美的工作,但後來我忘了備份數據庫,並在服務器升級中丟失了它。

我在2008年看了HierarchyID類型,但如果你關心的是同一級別的孩子的順序,那麼它就像是一個很大的麻煩。

+0

你能解釋一下你想要排序的是什麼? – 2009-11-19 14:05:45

回答

5

好吧,明白了:) - 這似乎在這裏工作。

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] 
+0

太棒了!出於某種原因,我曾想過在表中存儲路徑,但忘記了在查詢中生成路徑。 – AndyMcKenna 2009-11-19 15:41:33