2009-11-19 5 views
1

J'ai une table simple que j'utilise pour représenter une hiérarchie de catégories.SQL Recursive Menu Tri

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) 

Tout va bien sauf pour sélectionner l'arbre entier. Voici ma requête, j'ai enlevé mon ORDER BY parce qu'il ne fonctionne pas:

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 

Résultats:

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 

Le résultat que je veux est ceci:

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 

ce qui tue moi est-ce que j'ai fonctionné parfaitement avant, mais j'ai oublié de sauvegarder la base de données et l'ai perdue dans une mise à niveau du serveur.

J'ai regardé le type HierarchyID en 2008 mais il semble juste une grande douleur dans le cul si vous vous souciez de l'ordre des enfants au même niveau.

+0

Pourriez-vous expliquer ce que vous essayez de trier par? –

Répondre

5

Ok, j'ai compris :) - Cela semble fonctionner ici.

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

Génial! Pour une raison quelconque, j'avais pensé à stocker le chemin dans la table mais j'ai oublié de le générer dans la requête. – AndyMcKenna