2016-03-03 18 views
2

非常令人困惑的標題!讓我詳細說明一下。刪除遞歸CTE中包含ID的所有較短的子序列

我有兩個表;一個表示模塊(可包含其他模塊的某種類型的網頁),稱爲module_info,另一個表示模塊層次結構中每個頁面的位置,稱爲www_menu

module_info

+----------+------------+---------+ 
| moduleID | modulename | menu_id | 
+----------+------------+---------+ 
|  1 | tests  |  1 | 
|  2 | docs  |  2 | 
|  3 | mail  |  3 | 
|  4 | networks |  4 | 
|  5 | payroll |  5 | 
|  6 | admin  |  6 | 
|  7 | travel  |  7 | 
|  8 | bios  |  8 | 
+----------+------------+---------+ 

www_menu

+--------+--------+-------------------+------------------+ 
| menuID | parent |  title  |  location  | 
+--------+--------+-------------------+------------------+ 
|  1 |  0 | Tests    | modules/tests | 
|  2 |  0 | Testing Documents | modules/docs  | 
|  3 |  0 | Mailing Lists  | modules/mail  | 
|  4 |  1 | Network Services | modules/networks | 
|  5 |  1 | Payroll   | modules/payroll | 
|  6 |  2 | Administration | modules/admin | 
|  7 |  3 | Travel   | modules/travel | 
|  8 |  4 | Biographies  | modules/bios  | 
+--------+--------+-------------------+------------------+ 

這裏是我的查詢中顯示的層次:

WITH [root] AS 
(
    SELECT  www.menuID 
       ,CAST(www.title + ' (' + mi.modulename + ')' AS VARCHAR(200)) AS [path] 
       ,CAST(mi.id AS VARCHAR(20)) AS ids 
    FROM  [dbo].[module_info] AS mi 
    INNER JOIN [dbo].[WWW_Menu] www ON www.menuid = mi.menu_id 
    WHERE  www.location LIKE 'modules/%' 
UNION ALL 
    SELECT  leaf.menuID 
       ,CAST([root].[path] + ' > ' + leaf.title AS VARCHAR(200)) 
       ,CAST([root].ids + ',' + CONVERT(VARCHAR(4), mi.id) AS VARCHAR(20)) 
    FROM  [dbo].[WWW_Menu] AS leaf 
    INNER JOIN [root] ON leaf.parent = [root].menuID 
    INNER JOIN [dbo].[module_info] AS mi ON leaf.menuID = mi.menu_id 
) 
SELECT [path], ids FROM [root] 

並從上面的兩個表運行的結果:

+----------------------------------------+-------+ 
|     path     | ids | 
+----------------------------------------+-------+ 
| Tests         | 1  | 
| Testing Documents      | 2  | 
| Mailing Lists       | 3  | 
| Network Services      | 4  | 
| Payroll        | 5  | 
| Administration       | 6  | 
| Travel         | 7  | 
| Biographies       | 8  | 
| Tests > Network Services    | 1,4 | 
| Tests > Payroll      | 1,5 | 
| Testing Documents > Administration  | 2,6 | 
| Mailing Lists > Travel     | 3,7 | 
| Network Services > Biographies   | 4,8 | 
| Tests > Network Services > Biographies | 1,4,8 | 
+----------------------------------------+-------+ 

我將在選擇框中顯示這些結果,以便在所選模塊內搜索文檔。這是事情; Biographies,Network Services > BiographiesTests > Network Services > Biographies是相同的模塊。

對於每個模塊,我只是想顯示該模塊

+----------------------------------------+-------+ 
|     path     | ids | 
+----------------------------------------+-------+ 
| Tests         | 1  | 
| Testing Documents      | 2  | 
| Mailing Lists       | 3  | 
| Tests > Network Services    | 1,4 | 
| Tests > Payroll      | 1,5 | 
| Testing Documents > Administration  | 2,6 | 
| Mailing Lists > Travel     | 3,7 | 
| Tests > Network Services > Biographies | 1,4,8 | 
+----------------------------------------+-------+ 

在結束最長的層次串也許這是不正常一個SQL問題,並更好地通過某種迭代完成服務器端。但是,針對此問題的自包含SQL解決方案將是我的首選選項。謝謝。

回答

3

一種方法會涉及很多字符串操作。相反,當您瀏覽列表時,請跟蹤添加到列表中的最後一個模塊。然後使用row_number()獲得每個「最後」模塊的最長時間:

WITH [root] AS (
    SELECT www.menuID, 
      CAST(www.title + ' (' + mi.modulename + ')' AS VARCHAR(200)) AS [path], 
      CAST(mi.id AS VARCHAR(20)) AS ids, 
      mi.id as lastId 
    FROM [dbo].[module_info] mi INNER JOIN 
     [dbo].[WWW_Menu] www 
     ON www.menuid = mi.menu_id 
    WHERE www.location LIKE 'modules/%' 
    UNION ALL 
    SELECT leaf.menuID, 
      CAST([root].[path] + ' > ' + leaf.title AS VARCHAR(200)), 
      CAST([root].ids + ',' + CONVERT(VARCHAR(4), mi.id) AS VARCHAR(20)), 
      mi.id 
    FROM [dbo].[WWW_Menu] leaf INNER JOIN 
     [root] 
     ON leaf.parent = [root].menuID INNER JOIN 
     [dbo].[module_info] mi 
     ON leaf.menuID = mi.menu_id 
    ) 
SELECT [path], ids 
FROM (SELECT r.*, 
      ROW_NUMBER() OVER (PARTITION BY lastId ORDER BY length(path) DESC) as seqnum 
     FROM [root] r 
    ) r 
WHERE seqnum = 1; 
+0

這很好,謝謝。 – wdonahoe