Для этого вы можете использовать группирование и самостоятельное объединение.
SELECT substring_index(file_path, '\\', 4), file_path
from fs_walk_scan as ws1
WHERE 30<= (
select count(*) from fs_Walk_scan as ws2
where substring_index(ws2.file_path, '\\', 4) = substring_index(ws1.file_path, '\\', 4)
and ws2.file_size > ws1.file_size
and ws2.file_path <> ws1.file_path)
group by substring_index(file_path, '\\', 4)
Это все еще запрос O (n) (n является числом групп), но он более гибкий и короткий.
Edit:
Другой подход заключается в использовании переменных. Осуществимость вашей цели будет зависеть от того, как вы собираетесь выполнить этот запрос.
set @idx=0; set @cur_vol=0;
SELECT file_volume, file_path, file_size FROM (
SELECT file_volume, file_path, file_size,
IF(@cur_vol != a.file_volume, @idx:=1, @idx:=@idx+1) AS row_index,
IF(@cur_vol != a.file_volume, @cur_vol:=a.file_volume, 0) AS discard
FROM (SELECT substring_index(file_path, '\\', 4) as file_volume, file_path, file_size
FROM fs_walk_scan
ORDER BY substring_index(file_path,'\\',4), file_size DESC) AS a
HAVING row_index <= 30) AS b;
Я еще не пробовал этот код, но концепцию переменных можно использовать для этой цели.