フォルダにファイルがある場合にのみ、子の数を含めたいと想定しています。また、一番上のフォルダーは、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の間の結合でLEFT 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