2017-07-25 69 views
1

我想獲取所有祖先,所選類別和直接子項,並計算每個類別及其所有子項中的所有項目。如何在此sql查詢中獲取所有祖先,所選類別和直接子項

這是我做過什麼:

DECLARE @CategoryId INT = 8 
;WITH Re AS 
(
SELECT CategoryId, Name, ParentId, CategoryId RootId, 0 Depth, Sort = CAST(Name AS VARCHAR(MAX)) 
    FROM Category 
WHERE CategoryId = @CategoryId OR ParentId = @CategoryId 
UNION ALL 
SELECT C.CategoryId, C.Name, C.ParentId, RootId, Depth = Re.Depth + 1, Sort = Re.Sort + CAST(C.Name AS VARCHAR(200)) 
    FROM Re JOIN Category C ON Re.CategoryId = C.ParentId 
) 
SELECT Y.CategoryId, Y.Name, Y.ParentId, X.CatCount 
    FROM (SELECT RootId, COUNT(I.CategoryId) catCount 
      FROM Re LEFT OUTER JOIN Item I ON Re.CategoryId = I.CategoryId 
      GROUP BY RootId) X 
    JOIN (SELECT Re.CategoryId, Re.ParentId, Name, MAX(Depth) MaxDepth 
      FROM Re 
      GROUP BY Re.CategoryId, Re.ParentId, Name) Y ON Y.CategoryId = X.RootId 
ORDER BY CategoryId 

返回我想要什麼,但有一點問題是它。例如當@CategoryID = 8,此查詢應顯示:

CategoryId Name ParentId CatCount 
    0  A  NULL   16 
    1  B   0   10 
    7  H   1   4 
    8  I   7   2 
    13  N   8   1 

但它返回:當選擇子類別

CategoryId Name ParentId CatCount 
    8  I   7   2 
    13  N   8   1 

祖先未示出。

  1. 問題在哪裏?
  2. 如何優化此查詢?

我會感謝另外一個人幫助我

+0

你是什麼樣的輸入數據? –

+0

在此查詢或我的某個表中輸入樣本數據? – Masoud

+0

對於那個預期產出 –

回答

0

您的查詢不象你所說的,因爲與RootId問題(見下文評論) 你的CTE需要改變這個工作的:

DECLARE @CategoryId INT = 8 
;WITH Re AS 
(
    -- Anchor (this is the starting category) 
    SELECT CategoryId, Name, ParentId, CategoryId AS RootId, 
     0 AS Depth, Sort = CAST(Name AS VARCHAR(MAX)), CONVERT(VARCHAR(20), 'Root') AS Relation 
    FROM Category 
    WHERE CategoryId = @CategoryId 
    UNION ALL 
    -- Find children 
    SELECT C.CategoryId, C.Name, C.ParentId, C.CategoryId AS RootId, -- Fixed RootId problem 
     Depth = Re.Depth + 1, Sort = Re.Sort + CAST(C.Name AS VARCHAR(200)), CONVERT(VARCHAR(20), 'Child') AS Relation 
    FROM Re 
     INNER JOIN Category C ON Re.CategoryId = C.ParentId 
    WHERE Re.Relation IN('Root', 'Child') 
     -- I do not think this is necessary as we have established the anchor, see above 
     AND C.ParentId = @CategoryId 
    UNION ALL 
    -- Find Ancestors (Parents) 
    SELECT C.CategoryId, C.Name, C.ParentId, C.CategoryId AS RootId, -- Fixed RootId problem 
     Depth = Re.Depth - 1, Sort = Re.Sort + CAST(C.Name AS VARCHAR(200)), CONVERT(VARCHAR(20), 'Parent') AS Relation 
    FROM Re 
     INNER JOIN Category C ON C.CategoryId = Re.ParentId 
    WHERE Re.Relation IN('Root', 'Parent') 
) 
SELECT * FROM Re 

我已經使用了以下數據:

CREATE TABLE Category(CategoryId INT, Name VARCHAR(10), ParentID INT) 
SELECT * FROM Category 
INSERT INTO Category 
SELECT 0, 'A', NULL UNION ALL 
SELECT 1 , 'B', 0 UNION ALL 
SELECT 7 , 'H' , 1 UNION ALL 
SELECT 8 , 'I' , 7 UNION ALL 
SELECT 13 , 'N' , 8 
-- DROP TABLE Category 
+0

非常感謝。它工作正常。我改變了WHERE Re.Relation IN('Root','Child')到WHERE Re.Relation IN('Root','Child')和C.ParentId = @CategoryId,現在它正是我想要的。 – Masoud

+0

@Masoud - 我不確定你是否需要它。無論如何,我的示例運行良好。 – Alex

+0

我正在尋找所有的父母,只是直接選擇categoryId的孩子。你的查詢效果很好,並且想知道我的意思,但是它返回的是所有8的孩子,而不是它的直接孩子例如,如果13有一個孩子,@CategoryId = 8,它返回13和它的孩子,這是不需要的。但該解決方案對我非常有用,非常感謝。 – Masoud

相關問題