Je dois suivre les données dans SQL Server 2008 R2. SQLFiddle
Schéma:
CREATE TABLE [dbo]. [ICFilters] ( [ICFilterID] [int] IDENTITY (1,1) NOT NULL, [ParentID] [int] NOT NULL DEFAULT 0, [FilterDesc] [varchar] (50) NOT NULL, [Active] [tinyint] NOT NULL DEFAULT 1, CONTRAINTE [PK_ICFilters] CLÉ PRIMAIRE CLUSTERED ([ICFilterID] ASC) AVEC PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON ) LE [PRIMAIRE] ) LE [PRIMAIRE] INSERT INTO [dbo]. [ICFilters] (ParentID, FilterDesc, Active) Valeurs (0, «Type de produit», 1), (1, «ProdSubType_1», 1), (1, «ProdSubType_2», 1), (1, «ProdSubType_3», 1), (1, «ProdSubType_4», 1), (2, 'PST_1.1', 1), (2, 'PST_1.2', 1), (2, «PST_1.3», 1), (2, «PST_1.4», 1), (2, «PST_1.5», 1), (2, «PST_1.6», 1), (2, 'PST_1.7', 0), (3, «PST_2.1», 1), (3, 'PST_2.2', 0), (3, «PST_2.3», 1), (3, «PST_2.4», 1), (14, «PST_2.2.1», 1), (14, «PST_2.2.2», 1), (14, «PST_2.2.3», 1), (3, 'PST_2.8', 1)
Table:
| ICFILTERID | PARENTID | FILTERDESC | ACTIF | -------------------------------------------------- | 1 | 0 | Type de produit | 1 | | 2 | 1 | ProdSubType_1 | 1 | | 3 | 1 | ProdSubType_2 | 1 | | 4 | 1 | ProdSubType_3 | 1 | | 5 | 1 | ProdSubType_4 | 1 | | 6 | 2 | PST_1.1 | 1 | | 7 | 2 | PST_1.2 | 1 | | 8 | 2 | PST_1.3 | 1 | | 9 | 2 | PST_1.4 | 1 | | 10 | 2 | PST_1.5 | 1 | | 11 | 2 | PST_1.6 | 1 | | 12 | 2 | PST_1.7 | 0 | | 13 | 3 | PST_2.1 | 1 | | 14 | 3 | PST_2.2 | 0 | | 15 | 3 | PST_2.3 | 1 | | 16 | 3 | PST_2.4 | 1 | | 17 | 14 | PST_2.2.1 | 1 | | 18 | 14 | PST_2.2.2 | 1 | | 19 | 14 | PST_2.2.3 | 1 | | 20 | 3 | PST_2.8 | 1 |
Chaque ligne a l'ID de son parent et celle de la racine parentid = 0
. Les FilterDesc
s ne sont que des exemples de descriptions, donc je ne peux pas essayer de les analyser pour les commander.
La question
Est-il possible de sélectionner toutes les lignes de manière arborescente? Si c'est le cas, comment? Quand je dis «en forme d'arbre», je veux dire sélectionner récursivement le parent suivi de tous ses enfants, puis tous les enfants de chacun d'entre eux et ainsi de suite. Une première traversée d'arbre en profondeur.
Mes amis et moi avons essayé mais nous n'avons pas réussi à trouver des solutions de travail, mais nous continuerons d'essayer. Je suis assez nouveau dans sql, alors peut-être que cela peut être fait facilement et je rends les choses plus difficiles que nécessaire.
Exemple de sortie (souhaitée):
| ICFILTERID | PARENTID | FILTERDESC | ACTIF | -------------------------------------------------- | 1 | 0 | Type de produit | 1 | | 2 | 1 | ProdSubType_1 | 1 | | 6 | 2 | PST_1.1 | 1 | | 7 | 2 | PST_1.2 | 1 | | 8 | 2 | PST_1.3 | 1 | | 9 | 2 | PST_1.4 | 1 | | 10 | 2 | PST_1.5 | 1 | | 11 | 2 | PST_1.6 | 1 | | 12 | 2 | PST_1.7 | 0 | | 3 | 1 | ProdSubType_2 | 1 | | 13 | 3 | PST_2.1 | 1 | | 14 | 3 | PST_2.2 | 0 | | 17 | 14 | PST_2.2.1 | 1 | | 18 | 14 | PST_2.2.2 | 1 | | 19 | 14 | PST_2.2.3 | 1 | | 15 | 3 | PST_2.3 | 1 | | 16 | 3 | PST_2.4 | 1 | | 20 | 3 | PST_2.8 | 1 | | 4 | 1 | ProdSubType_3 | 1 | | 5 | 1 | ProdSubType_4 | 1 |
la source
Réponses:
OK, assez de cellules cérébrales sont mortes.
SQL Fiddle
la source
[FilterDesc]
colonne sont fictives et cet ordre est inutile / sans importance. Suivant la logique de la réponse de @Travis Gan, tout ce que l'on doit faire pour obtenir ce classement est d'en ajouter un autreCAST
auLevel
. par exemple.Level + CAST( CAST(i.[ICFilterID] AS varbinary(max)) AS Level
DevientLevel + CAST(i.[FilterDesc] AS varbinary(max)) + CAST(i.[ICFilterID] AS varbinary(max)) AS Level
.Ce qui précède ne semble pas fonctionner correctement pour moi. Imaginez une configuration à 2 tables avec des données de type facebook. Le tableau 1, a PostId + vous d'autres champs. PostId est incrémenté automatiquement et, évidemment, dans votre interface, vous trierez DESC pour avoir le dernier message en haut.
Maintenant, pour le tableau des commentaires. Tableau 2 Ce tableau CommentId est la clé primaire, numéro automatique. Dans votre interface graphique, vous souhaitez l'afficher en ASC, afin que lors de la lecture du fil, cela ait du sens. (le plus ancien (nombre le plus petit) en haut) Les autres clés importantes du tableau 2 sont: PostId (FK retour aux publications) et ParentId (FK à CommentId) où ParentId sera NULL s'il s'agit du commentaire "racine" sur une publication. Si quelqu'un RÉPOND à un commentaire, le parentId sera rempli avec le commentid.
J'espère que vous obtenez la dérive. Le CTE ressemblera à ceci:
Exemple de sortie
Sur F / B post 105, il y avait deux commentaires (CommentIds 1 et 2) Quelqu'un a ensuite répondu sur Comment1 (CommentId 5, ParentId 1), puis quelqu'un d'autre a commenté cette réponse, ainsi de suite Comment5 (CommentId 6, ParentId 6)
Et l'alto, la séquence est correcte, sous le post, vous pouvez maintenant afficher les commentaires dans la bonne séquence. Pour mettre en retrait les messages afin qu'ils se forment et se dessinent comme dans Facebook (plus le niveau est profond, plus il doit être margé à partir de la gauche), j'ai également une colonne appelée Retrait. Les racines sont 0, puis dans l'union, nous avons c.Indent + 1 AS Indent Dans le code, vous pouvez maintenant multiplier le retrait avec supposons 32px et afficher les commentaires dans une hiérarchie et un contour agréables.
Je ne vois aucun problème à utiliser la clé primaire d'incrémentation automatique CommentId comme force motrice pour la création de ma SortKey, car il y a un meilleur changement de vous gâcher les dates (date de commentaire) que de gâcher une clé gérée par la base de données qui contient +1
la source
Cela vous donnera tous les descendants et le niveau.
J'espère que cela t'aides :)
la source