Быстро суммировать столбец дочерних строк много раз в SQL - PullRequest
0 голосов
/ 24 мая 2019

У меня есть база данных 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 ]

1 голос
/ 24 мая 2019

Для этого примера таблицы:

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;
0 голосов
/ 24 мая 2019

Используйте GROUP BY.

Group by путь и в операторе select используйте функцию агрегирования sum() для столбца размера.

Ваш запрос будет выглядеть примерно так, как показано ниже,

Select path, sum(size) from table_name
where path like 'path/python%'
Group by path

Это выдаст как path and size.

Теперь вам не нужно выполнять итерации для всех файлов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...