如何在递归查询中获取项目的级别和计数

时间:2012-10-15 17:13:06

标签: sql sql-server sql-server-2008

WITH cte(folder_id, parent_id, folder_name)
AS
(
    select folder.folder_id, folder.parent_id, folder.folder_name
    FROM Folder_Table [folder] 
        JOIN File_Table [file] on [folder].[folder_id] = [file].[folder_id]
    union all
    select Folder_Table.folder_id,Folder_Table.parent_id,Folder_Table.folder_name
    from cte 
        join Folder_Table on cte.parent_id = Folder_Table.folder_id
)
SELECT distinct * FROM cte

在此查询中,我需要获取该级别的项目级别和子级数 如果有孩子

2 个答案:

答案 0 :(得分:2)

轻松获取Level

WITH cte(folder_id, parent_id, folder_name, level)
AS
(
    SELECT
       folder.folder_id, folder.parent_id, folder.folder_name, Level = 0
    FROM 
       Folder_Table [folder] 
    INNER JOIN 
       File_Table [file] on [folder].[folder_id] = [file].[folder_id]

    UNION ALL

    SELECT 
       Folder_Table.folder_id, Folder_Table.parent_id, Folder_Table.folder_name, CTE.Level + 1
    FROM
       cte 
    INNER JOIN 
       Folder_Table on cte.parent_id = Folder_Table.folder_id
)
SELECT DISTINCT * FROM cte

但是得到孩子的数量相当棘手 - 你几乎必须在任何给定的级别“预览”下一级别;抱歉,我想不出任何简单的方法。

答案 1 :(得分:0)

我假设您只想在文件夹中有文件时包含子项的计数。另外,我假设最顶层的文件夹与parent_id具有相同的folder_id。

WITH cte (folder_id, parent_id, folder_name) AS
(
   SELECT folder.folder_id, folder.parent_id, folder.folder_name
   FROM Folder_Table [folder] JOIN File_Table [file] ON [folder].[folder_id] = [file].[folder_id]
   WHERE [folder].parent_id = [folder].folder_id
   UNION ALL
   SELECT folder.folder_id, folder.parent_id, folder.folder_name
   FROM cte JOIN Folder_Table [folder] ON cte.folder_id = folder.parent_id
   WHERE folder.parent_id != folder.folder_id
)
SELECT parent_id, COUNT(1) as [Number of children]
 FROM cte
WHERE folder_id != parent_id
GROUP BY parent_id

请注意,当该文件夹中没有文件时,查询不会返回父文件夹,但要在Folder_Table和File_Table之间的连接中使用L​​EFT OUTER JOIN来更改它是相当容易的

要获得该级别,它将与上述查询非常相似:

WITH cte (folder_id, parent_id, folder_name, level) AS
(
   SELECT folder.folder_id, folder.parent_id, folder.folder_name, 0
   FROM Folder_Table [folder] JOIN File_Table [file] ON [folder].[folder_id] = [file].[folder_id]
   WHERE [folder].parent_id = [folder].folder_id
   UNION ALL
   SELECT folder.folder_id, folder.parent_id, folder.folder_name, level+1
   FROM cte JOIN Folder_Table [folder] ON cte.folder_id = folder.parent_id
   WHERE folder.parent_id != folder.folder_id
)
SELECT * FROM cte