J'essaie d'effectuer ce que je crois que c'est une récursion difficile à l'aide d'un CTE est SQL Server 2008. Je n'arrive pas à envelopper ma tête autour de celui-ci.
Dans les exemples ci-dessous, vous pouvez assumer une profondeur fixe de 3 ... rien ne sera jamais inférieur à cela. Dans la vie réelle, la profondeur est "plus profonde" mais toujours corrigée. Dans l'exemple, j'ai essayé de le simplifier certains. P>
Mes données d'entrée sont comme ci-dessous. P>
LEVEL1_ID LEVEL2_ID LEVEL3_ID LEVEL1_NAME LEVEL2_NAME LEVEL3_NAME -------------------------------------------------------------------------------- 1 NULL NULL A NULL NULL 1 2 NULL A B NULL 1 2 3 A B C 1 4 NULL A D NULL
3 Réponses :
Pas vraiment tout ce difficile à faire: me donne une sortie de: p> comme une note latérale: le "Profondeur" pourrait être facilement calculé par le CTE et vous n'avez pas nécessairement besoin de stocker cela dans votre table (voir la colonne Niveau Code> J'ai ajouté): P>
;WITH cte AS
(
SELECT
CAST('/' + Name AS VARCHAR(50)) as 'CteName', ID,
1 AS 'Level'
FROM dbo.YourTable
WHERE parent_id IS NULL
UNION ALL
SELECT
CAST(cte.CteName + '/' + Name AS VARCHAR(50)), t.ID,
cte.Level + 1 AS 'Level'
FROM dbo.YourTable t
INNER JOIN cte ON t.parent_id = cte.id
)
SELECT cteName FROM cte
ORDER BY Level, ID
C'est génial. Merci! J'ai changé la question un peu mais c'est excellent. Je peux certainement utiliser cet exemple.
Avec ce code, vous n'avez pas le problème de rejoindre les niveaux plusieurs fois? Par exemple, au cours de la 1ère exécution de la course récursive, vous rejoindrez les niveaux 1 avec les niveaux 2, au cours de la 2e exécution, vous rejoindrez à nouveau les niveaux 1 avec les niveaux 2 et les niveaux 2 avec les niveaux 3, etc. .. les lignes en double. sont "supprimés" B l'opérateur du syndicat, mais cela fera beaucoup de jointures en double.
@MUNISSOR: Non, SQL Server gérera cette version spécifique du CTE en tant que CTE récursive (Union tout est le mot clé requis pour cela) et fera tout le travail nécessaire nécessaire. Aucun niveau n'est joint à plusieurs fois.
Vous avez raison, le syndicat préservera toutes les valeurs dupliquées, le cas échéant.
Je ne me souviens pas de toi peut faire une sous-requête dans un CTE.
Je n'ai pas de copie de SQL Server ici, mais vous pouvez essayer avec ce code: P>
WITH cte(id, path, level) AS ( SELECT id, '/' + name, level FROM yourtable WHERE level = 1 UNION ALL SELECT y.id, c.name + '/' + y.name, y.level FROM yourtable y INNER JOIN cte c ON c.id = y.parent_id WHERE level = (SELECT max(level)+1 from cte) ) SELECT path from cte
Je reçois seulement une tonne d'erreurs: MSG 207, niveau 16, état 1, ligne 6 Nom de colonne non valide "Niveau". MSG 207, niveau 16, état 1, ligne 4 Nom de colonne non valide "Niveau". MSG 253, niveau 16, État 1, ligne 1 Membre récursif d'une expression de table commune 'CTE' a plusieurs références récursives.
Ok donc tu ne peux pas utiliser de sous-requête;)
;WITH Vals AS ( SELECT CASE DEPTH WHEN 1 THEN ID ELSE NULL END 'LEVEL1_ID ', CASE DEPTH WHEN 2 THEN ID ELSE NULL END 'LEVEL2_ID ', CASE DEPTH WHEN 3 THEN ID ELSE NULL END 'LEVEL3_ID ', CASE DEPTH WHEN 1 THEN NAME ELSE NULL END 'LEVEL1_NAME', CASE DEPTH WHEN 2 THEN NAME ELSE NULL END 'LEVEL2_NAME', CASE DEPTH WHEN 3 THEN NAME ELSE NULL END 'LEVEL3_NAME', ID 'PRMID' FROM #Table1 WHERE parentId IS NULL UNION ALL SELECT CASE DEPTH WHEN 1 THEN ID ELSE LEVEL1_ID END 'LEVEL1_ID ', CASE DEPTH WHEN 2 THEN ID ELSE LEVEL2_ID END 'LEVEL2_ID ', CASE DEPTH WHEN 3 THEN ID ELSE LEVEL3_ID END 'LEVEL3_ID ', CASE DEPTH WHEN 1 THEN NAME ELSE LEVEL1_NAME END 'LEVEL1_NAME', CASE DEPTH WHEN 2 THEN NAME ELSE LEVEL2_NAME END 'LEVEL2_NAME', CASE DEPTH WHEN 3 THEN NAME ELSE LEVEL3_NAME END 'LEVEL3_NAME', ID 'PRMID' FROM #Table1 inner join Vals on #Table1.parentId=PRMID ) SELECT * from Vals
Je ne pouvais pas comprendre quelle logique vous postulez en regardant votre sortie. Je pense que la dernière ligne doit être
/ b / d code> car l'ID parent de
d code> est 2 I.e.
B code> B code>
vient de mettre à jour la question. Pardon.
Encore la même chose. Dans la rangée n ° 4, pourquoi avez-vous besoin de niveau1_id comme
1 code> lorsque son identifiant parent est 2?
Je pense que l'entrée et la sortie sont correctes maintenant. ID de 1 a parent_id de null.