#sql #sqlite #common-table-expression #recursive-query
#sql #sqlite #common-table-expression #рекурсивный запрос
Вопрос:
У меня есть это хорошее рекурсивное предложение WITH:
WITH RECURSIVE split(seq, word, str) AS (
SELECT 0, null, replace('name one two three.jpg', '.jpg', ' ')
UNION ALL SELECT
seq 1,
substr(str, 0, instr(str, ' ')),
substr(str, instr(str, ' ') 1)
FROM split WHERE str != ''
) SELECT word FROM split where seq>1
И результат:
one
two
three
Теперь, как я могу повторно использовать это предложение, применяя SELECT name from Images
вместо этой постоянной строки 'name one two three.jpg'
?
Цель состоит в том, чтобы извлечь все уникальные строки ‘ suffix’, которые можно найти во всем наборе имен изображений. Например, это образец данных:
DROP TABLE IF EXISTS ImagesTemp;
CREATE TEMP TABLE ImagesTemp (name );
INSERT INTO ImagesTemp (name)
VALUES
('IMG_0403 newport malboro kool.jpg'),
('IMG_0404 camel newport.JPG'),
('IMG_0405 dunhill doral malboro.png');
SELECT * from ImagesTemp
И ожидаемый результат:
word count
malboro 2
newport 2
kool 1
dunhill 1
doral 1
camel 1
Комментарии:
1. Опубликуйте образцы данных и ожидаемые результаты для уточнения.
Ответ №1:
Рассмотрите возможность замены привязки CTE на select из вашей таблицы, например:
WITH RECURSIVE split(seq, word, str) AS (
SELECT 0, null, replace(name, '.jpg', ' ')
FROM images
UNION ALL
SELECT
seq 1,
substr(str, 0, instr(str, ' ')),
substr(str, instr(str, ' ') 1)
FROM split
WHERE str != ''
)
SELECT word FROM split WHERE seq>1
Комментарии:
1. Сначала я попробовал это, но это заставляло «DB Browser for SQLite» зависать. Добавление LIMIT 10000 внутри оператора inner select предотвратило зависание запроса, хотя я не доверял результатам. Но спасибо, что вы указали мне на решение.
Ответ №2:
Понял это! Хитрость здесь заключалась в том, чтобы убедиться, что имя файла заканчивается на ‘ ‘, чтобы рекурсивное предложение работало без зависания. Я также добавил счетчик для расширений имен файлов.
WITH RECURSIVE split(seq, word, str, filename) AS (
SELECT 0, null, lower(replace(name, '.', ' .')||' '), name from ImagesTemp
UNION ALL
SELECT
seq 1,
substr(str, 0, instr(str, ' ')),
substr(str, instr(str, ' ') 1),
filename
FROM split
WHERE str != ''
)
SELECT distinct word, count(*) as count, filename as sample
FROM split WHERE word != '' and seq>1
GROUP BY word
ORDER BY count DESC
Результат:
word count sample
newport 2 IMG_0403 newport malboro kool.jpg
malboro 2 IMG_0403 newport malboro kool.jpg
.jpg 2 IMG_0404 camel newport.JPG
kool 1 IMG_0403 newport malboro kool.jpg
dunhill 1 IMG_0405 dunhill doral malboro.png
doral 1 IMG_0405 dunhill doral malboro.png
camel 1 IMG_0404 camel newport.JPG
.png 1 IMG_0405 dunhill doral malboro.png