You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

编写MySQL/Hive查询聚合文件夹文件数,统计文件最多的文件夹

Hey there! Let's tackle this problem of counting files per folder—including parent folders and their subfolders, then finding which folder has the most files. First, let's assume we have a table file_system that tracks every file's full path (like /mysite/current/report.pdf). I'll cover solutions for both MySQL 8.0+ and Hive since they're common for this kind of task.

Solution: Count Files by Folder (With Parent/Subfolder Distinction)

1. MySQL 8.0+ Implementation (Recursive CTEs for Hierarchy)

Split Paths & Count Files for All Folders

Recursive CTEs let us "climb up" each file's path to extract every parent folder, then we can aggregate the file counts for each level:

WITH RECURSIVE folder_paths AS (
    -- Start with the first level of each file's path
    SELECT
        full_path,
        SUBSTRING_INDEX(full_path, '/', 2) AS folder, -- e.g., '/mysite' from '/mysite/current/file.txt'
        1 AS depth
    FROM file_system
    WHERE full_path != '/' -- Skip root if it's in the table
    UNION ALL
    -- Recursively extract higher parent folders
    SELECT
        fp.full_path,
        SUBSTRING_INDEX(fp.folder, '/', depth + 1) AS folder,
        depth + 1 AS depth
    FROM folder_paths fp
    WHERE SUBSTRING_INDEX(fp.folder, '/', depth + 1) != '' -- Stop at root
)
-- Aggregate stats and label folder type
SELECT
    folder,
    COUNT(DISTINCT full_path) AS total_files,
    -- Mark if it's a parent folder (has subfolders) or leaf subfolder
    CASE WHEN EXISTS (
        SELECT 1 FROM folder_paths fp2 
        WHERE fp2.folder LIKE CONCAT(folder, '/%')
    ) THEN 'Parent Folder (contains subfolders)' ELSE 'Subfolder (leaf level)' END AS folder_type
FROM folder_paths
GROUP BY folder
ORDER BY total_files DESC;

Find the Folder(s) With the Most Files

If you only care about the top folder(s) by file count, wrap the stats in another CTE to filter for the maximum value:

WITH RECURSIVE folder_paths AS (
    SELECT
        full_path,
        SUBSTRING_INDEX(full_path, '/', 2) AS folder,
        1 AS depth
    FROM file_system
    WHERE full_path != '/'
    UNION ALL
    SELECT
        fp.full_path,
        SUBSTRING_INDEX(fp.folder, '/', depth + 1) AS folder,
        depth + 1 AS depth
    FROM folder_paths fp
    WHERE SUBSTRING_INDEX(fp.folder, '/', depth + 1) != ''
),
folder_stats AS (
    SELECT
        folder,
        COUNT(DISTINCT full_path) AS total_files,
        CASE WHEN EXISTS (
            SELECT 1 FROM folder_paths fp2 
            WHERE fp2.folder LIKE CONCAT(folder, '/%')
        ) THEN 'Parent Folder' ELSE 'Subfolder' END AS folder_type
    FROM folder_paths
    GROUP BY folder
)
SELECT *
FROM folder_stats
WHERE total_files = (SELECT MAX(total_files) FROM folder_stats);

2. Hive Implementation (For Big Data Scenarios)

Hive doesn't support recursive CTEs, but we can use split and LATERAL VIEW explode to break down paths into their components:

Split Paths & Count Files for All Folders

WITH folder_paths AS (
    SELECT
        full_path,
        concat_ws('/', collect_list(path_part)) AS folder
    FROM file_system
    -- Strip leading slash, split path into parts, then explode each part with its position
    LATERAL VIEW posexplode(split(regexp_replace(full_path, '^/', ''), '/')) exploded AS pos, path_part
    GROUP BY full_path, pos
)
-- Aggregate and label folder type
SELECT
    folder,
    COUNT(DISTINCT full_path) AS total_files,
    CASE WHEN EXISTS (
        SELECT 1 FROM folder_paths fp2 
        WHERE fp2.folder LIKE concat(folder, '/%')
    ) THEN 'Parent Folder' ELSE 'Subfolder' END AS folder_type
FROM folder_paths
GROUP BY folder
ORDER BY total_files DESC;

Find the Folder(s) With the Most Files

Use a window function to rank folders by file count and pick the top ones:

WITH folder_paths AS (
    SELECT
        full_path,
        concat_ws('/', collect_list(path_part)) AS folder
    FROM file_system
    LATERAL VIEW posexplode(split(regexp_replace(full_path, '^/', ''), '/')) exploded AS pos, path_part
    GROUP BY full_path, pos
),
folder_stats AS (
    SELECT
        folder,
        COUNT(DISTINCT full_path) AS total_files,
        CASE WHEN EXISTS (
            SELECT 1 FROM folder_paths fp2 
            WHERE fp2.folder LIKE concat(folder, '/%')
        ) THEN 'Parent Folder' ELSE 'Subfolder' END AS folder_type,
        RANK() OVER(ORDER BY COUNT(DISTINCT full_path) DESC) AS rnk
    FROM folder_paths
    GROUP BY folder
)
SELECT folder, total_files, folder_type
FROM folder_stats
WHERE rnk = 1;

Key Notes

  • Parent Folder Counts: For example, /mysite's total includes every file in /mysite/current, /mysite/backup, and any other subfolders—exactly what you requested.
  • Folder Type Distinction: We check for existing subfolders by looking for paths that start with the current folder's path plus a slash.
  • Duplicate Protection: COUNT(DISTINCT full_path) ensures we don't count the same file multiple times if there are duplicate entries in the table.

内容的提问来源于stack exchange,提问作者summerNight

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 07:37:01