我有一个 sqlite 文件表,其中每一行代表一个文件。 一行包含文件的父目录 ID、文件名、目录 ID(如果文件是符号链接)以及文件大小(以百分比表示)。
符号链接文件可以是有效的(指向现有目录)或损坏的(指向丢失的目录)
我想将这个结构压平到一定的深度。也就是说,在遍历层次结构时包括所有叶文件和损坏的符号链接以及该深度的有效符号链接,但不包括通向该深度的有效符号链接。最终,目标是重新计算扁平化文件的 size_percent,但这不是具有挑战性的部分。
为了说明这一点,我将省略此示例中的 size_percent 并重点关注展平部分:
假设层次结构如下
D1/
D1F1
D1F2
D2/
D2F1
D2F2 -> D0/ # broken symlink
D2F3 -> D1/ # valid symlink
D3/
D3F1
D3F2 -> D0/ # broken symlink
D3F3 -> D2/ # valid symlink
我的查询完全展平了结构,直到叶文件并包括沿途损坏的符号链接。
D1/
D1F1
D1F2
D2/
D2F1
D2F2 -> D0/
D1F1
D1F2
D3/
D3F1
D3F2 -> D0/
D2F1
D2F2 -> D0/
D1F1
D1F2
但是,我不清楚如何概括它,使其可以支持任意深度而不是一直深入。 例如,展平到深度 k = 2 应该给出:
D1/
D1F1
D1F2
D2/
D2F1
D2F2 -> D0/
D1F1
D1F2
D3/
D3F1
D3F2 -> D0/
D2F1
D2F2 -> D0/
D2F2 -> D1/
上面示例的数据和我的查询如下:
CREATE TABLE files AS WITH tmp(directory_id, filename, symlink, size_percent) AS (
VALUES
('D1', 'D1 F1', NULL, 0.5),
('D1', 'D1 F2', NULL, 0.5),
('D2', 'D2 F1', NULL, 0.5),
('D2', 'D2 F2', 'D0', 0.3),
('D2', 'D2 F3', 'D1', 0.2),
('D3', 'D3 F1', NULL, 0.1),
('D3', 'D3 F2', 'D0', 0.2),
('D3', 'D3 F3', 'D2', 0.7)
)
SELECT * FROM tmp;
WITH RECURSIVE flattened(directory_id, filename, symlink, depth, size_percent) AS (
SELECT
directory_id,
filename,
symlink,
0,
size_percent
FROM files
WHERE symlink is NULL -- regular file
OR symlink NOT IN (SELECT DISTINCT directory_id FROM files) -- broken symlink file
UNION ALL
SELECT
files.directory_id,
flattened.filename,
flattened.symlink,
flattened.depth + 1,
flattened.size_percent * files.size_percent
FROM flattened
JOIN files ON (files.symlink = flattened.directory_id)
)
SELECT * FROM flattened
ORDER BY directory_id, depth, filename
;