在SQL中快速多次汇总子行的列

时间:2019-05-24 05:02:16

标签: python sqlite

我有一个SQLite数据库,可在其中跟踪计算机上的所有文件和目录。对于每个文件,我都会跟踪大小。 文件和目录用列is_directory进行区分。

我想写一个查询来根据文件路径计算所有目录的大小。

例如:

如果我们有以下文件:

/projects/python/main.py 
/projects/python/util.py

然后,/projects/python的目录大小将是这两个文件大小的总和。

对一个目录执行此操作很容易,但是如何快速对数据库中的所有文件夹执行此操作?

现在,我使用python脚本来获取所有文件夹,然后,我用以下内容逐一计算它们的大小。

UPDATE files 
SET size = 
   (
      SELECT COALESCE(SUM(size),0)
      FROM files 
      WHERE is_directory = 0 AND
      path LIKE '/projects/python%'
   ),
WHERE path = '/projects/python'

这可以工作,但是对于许多目录来说速度很慢。

2 个答案:

答案 0 :(得分:1)

给出此示例表:

CREATE TABLE filesystem(path TEXT PRIMARY KEY, size INTEGER, is_directory INTEGER);
INSERT INTO filesystem VALUES ('/',0,1)
  , ('/projects/',0,1),('/projects/README.md',20,0)
  , ('/projects/python/',0,1), ('/projects/python/main.py',50,0)
  , ('/projects/python/util.py',70,0);

此查询:

SELECT path AS directory
     , (SELECT sum(size)
        FROM filesystem AS f2
        WHERE f2.path LIKE f.path || '%' AND f2.is_directory = 0) AS total_size
FROM filesystem AS f
WHERE is_directory = 1
ORDER BY path;

将产生:

directory             total_size
--------------------  ----------
/                     140       
/projects/            140       
/projects/python/     120       

基本上,对于每个目录,它都将以该目录作为其路径前缀的所有条目的大小相加。


要更新目录行的大小,而不是即时计算它们:

UPDATE filesystem AS f
SET size = (SELECT sum(f2.size)
            FROM filesystem AS f2
            WHERE f2.path LIKE f.path || '%' AND f2.is_directory = 0)
WHERE f.is_directory = 1;

答案 1 :(得分:0)

使用@Entity(tableName = "entry_table") data class Entry(@PrimaryKey(autoGenerate = true) val id: Int, val username: String, val hint: String, val password: String)

GROUP BY路径,在Group by语句中,在大小列上使用聚合函数select

您的查询将如下所示,

sum()

它将输出为Select path, sum(size) from table_name where path like 'path/python%' Group by path

现在,您无需对所有文件进行迭代。