2012-01-12 1 views
4

J'ai une base de données de forum qui stocke les informations de forum dans une seule colonne. Le forum permet des sous-forums illimités.Requête récursive avec CTE - SUM de colonnes enfants pour un parent donné

Nom de la table - Forums

| ForumID | ParentForumID | Name | Description | TopicCount | ReplyCount | LastPost | 

Étant donné un ForumID comme paramètre que je suis en train de SUM le TopicCount et ReplyCount pour toutes les entrées de l'enfant. J'essaye également de renvoyer la dernière LastPost, qui est spécifiée comme DATETIME.

J'ai cherché google et ce forum et je comprends que je devrais utiliser un CTE récursif mais j'ai quelques difficultés à comprendre la syntaxe. Voici mon CTE - travail en cours.

WITH CTE (ForumID, ParentForumID) 
    AS 
    (
     SELECT ForumID AS Descendant, ParentForumID as Ancestor 
     FROM forums 
     UNION ALL 
     SELECT e.Ancestor 
     FROM 
      CTE as e 
      INNER JOIN CTE AS d 
      ON Descendant = d.ParentForumID 
    ) 
    SELECT e.Descendant, SUM(TopicCount) AS topics, SUM(ReplyCount) AS replys 
    FROM CTE e 
    WHERE e.Ancestor = 1 

1 = Paramètre pour l'ID du forum.

Merci d'avance pour l'aide!

+0

Avez-vous seulement besoin d'enfants ou avez-vous besoin de petits-enfants et d'arrière-petits-enfants, etc.? – cadrell0

Répondre

5

Vous faites OK - vous êtes assez proche :-)

Fondamentalement, vous devez:

  • définissent le premier forum à cueillie avant le CTE
  • créer un " ancre » requête à ce forum défini
  • itérer puis sur tous les enfants et somme les TopicCount et ReplyCount compteurs

Donc, votre code devrait ressembler à ceci:

DECLARE @RootForumID INT 
SET @RootForumID = 1 -- or whatever you want... 

;WITH CTE AS 
(
    -- define the "anchor" query - select the chosen forum 
    SELECT 
     ForumID, TopicCount, ReplyCount, LastPost 
    FROM 
     dbo.forums 
    WHERE 
     ForumID = @RootForumID 

    UNION ALL 

    -- select the child rows 
    SELECT 
     f.ForumID, f.TopicCount, f.ReplyCount, f.LastPost 
    FROM 
     dbo.forums f 
    INNER JOIN 
     CTE on f.ParentForumID = CTE.ForumID 
) 
SELECT 
    SUM(TopicCount) AS topics, 
    SUM(ReplyCount) AS replys, 
    MAX(LastPost) AS 'Latest Post' 
FROM 
    CTE 

Bien sûr, vous pouvez envelopper ceci dans une procédure stockée qui prendrait comme paramètre la « racine » initial ForumID.

+0

Vous devez donc déclarer l'ID en premier. Votre solution a parfaitement fonctionné. Merci – user1145751

+0

@ user1145751: c'est comme ça que je le fais normalement (à l'intérieur d'un proc stocké, l'identifiant "root" est passé en paramètre) - mais je suis sûr qu'il y a probablement d'autres façons d'y parvenir! –

Questions connexes