Условие
Таблица Tree(id, p_id) — дерево, где p_id — id родителя. Для корня p_id IS NULL.
Для каждого id верните тип: Root, Inner, Leaf. Сортировка по id.
Структура данных
Tree(id INT, p_id INT NULL)
Решение
Лобовое — три проверки
SELECT
id,
CASE
WHEN p_id IS NULL THEN 'Root'
WHEN id IN (SELECT DISTINCT p_id FROM Tree WHERE p_id IS NOT NULL) THEN 'Inner'
ELSE 'Leaf'
END AS type
FROM Tree
ORDER BY id;Эффективнее — left self-join за один проход
SELECT
t.id,
CASE
WHEN t.p_id IS NULL THEN 'Root'
WHEN COUNT(c.id) > 0 THEN 'Inner'
ELSE 'Leaf'
END AS type
FROM Tree t
LEFT JOIN Tree c ON c.p_id = t.id
GROUP BY t.id, t.p_id
ORDER BY t.id;COUNT(c.id) > 0 — у t есть дети → внутренний.
Подводные камни
IN (NULL, ...). ЕслиTree.p_idсодержит NULL и забытьWHERE p_id IS NOT NULLв подзапросе —INвернёт UNKNOWN для всего, иInnerникогда не сработает.- Дерево с одним узлом. Если
Treeсодержит только корень — онRoot, неLeaf. CASE проверяетp_id IS NULLпервым — норм. - Дубли id. В реальных БД primary key защищает, но если данные грязные —
GROUP BYвсё равно даст один тип на id.
Эталонный ответ
CASE с тремя ветками: NULL → Root, есть дети → Inner, иначе Leaf. Через self-LEFT-JOIN Tree t LEFT JOIN Tree c ON c.p_id = t.id и COUNT(c.id) > 0.