36. Найти папки с AVI-файлами или без файлов
Условие задачи:
Даны таблицы folder и file.
Необходимо вывести названия папок, которые удовлетворяют хотя бы одному условию:
содержат хотя бы один файл с расширением
.avi;не содержат ни одного файла.
Код:
CREATE TABLE folder (
id uuid PRIMARY KEY,
name text NOT NULL
);
CREATE TABLE file (
id uuid PRIMARY KEY,
name text NOT NULL,
folder_id uuid NOT NULL,
CONSTRAINT fk__file__folder_id
FOREIGN KEY (folder_id) REFERENCES folder(id)
);
Спойлеры к решению
Подсказки
💡 Для условия «есть хотя бы один AVI-файл» удобно использовать
💡 Для пустой папки можно проверить отсутствие любых файлов через
💡 Альтернативный вариант —
💡 При использовании
EXISTS.💡 Для пустой папки можно проверить отсутствие любых файлов через
NOT EXISTS.💡 Альтернативный вариант —
LEFT JOIN с проверкой file.id IS NULL.💡 При использовании
JOIN может потребоваться DISTINCT.Решение
Вариант через EXISTS и NOT EXISTS:
SELECT f.name
FROM folder f
WHERE EXISTS (
SELECT 1
FROM file fi
WHERE fi.folder_id = f.id
AND fi.name LIKE '%.avi'
)
OR NOT EXISTS (
SELECT 1
FROM file fi
WHERE fi.folder_id = f.id
);
Первая часть проверяет, есть ли в папке хотя бы один AVI-файл:
EXISTS (
SELECT 1
FROM file fi
WHERE fi.folder_id = f.id
AND fi.name LIKE '%.avi'
)
Вторая часть выбирает папки, в которых вообще нет файлов:
NOT EXISTS (
SELECT 1
FROM file fi
WHERE fi.folder_id = f.id
)
Альтернативный вариант через LEFT JOIN:
SELECT DISTINCT f.name
FROM folder f
LEFT JOIN file fi
ON fi.folder_id = f.id
WHERE fi.name LIKE '%.avi'
OR fi.id IS NULL;
LEFT JOIN сохраняет пустые папки, а DISTINCT убирает повторения, если в одной папке находится несколько AVI-файлов.