使用 SQL 将目录展平至一定深度

问题描述 投票:0回答:1

我有一个 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
;

sql sqlite
1个回答
0
投票

我相信你可以添加一个 WHERE 子句,例如

WHERE flattened.depth + 1 < 2
  • 其中 2 可以作为绑定参数传递,因此是
    WHERE flattened.depth + 1 < ?

然而,结果并没有达到你的预期,而是:-

enter image description here

  • D2F2 -> D1/
    不存在(也不存在 WHERE 子句),也许这是一个拼写错误,因为没有 WHERE 子句,结果是:-

enter image description here

  • 即结果是相同的,但排除了深度为 2 的 2 行。
© www.soinside.com 2019 - 2024. All rights reserved.