Problem
Difficulty : Medium
Write an SQL query to report the type of each node in the tree.
My Solution 1
CASE 문을 활용해 Node type을 출력한다.
- 부모노드가 없는 경우 Root
- 부모노드가 있고, 자기자신이 누군가의 부모노드인 경우 Inner
- IN SUBQUERY
- 부모노드가 있고, 자기자신이 누군가의 부모노드가 아닌 경우 Leaf
SELECT
id,
CASE
WHEN p_id IS NULL THEN "Root"
WHEN id IN (SELECT p_id from Tree) THEN "Inner"
ELSE "Leaf"
END AS `type`
FROM Tree t1
-- ordered by id in ascending order.
ORDER BY 1
My Solution 2
IN Subquery를 사용하지 않고 셀프조인으로 코드를 작성할 수 있다.
SELF JOIN 결과, t2.id
는 t1.id
의 자식노드이다.
LEFT JOIN Tree t2 ON t1.id=t2.p_id
t1.p_id
가 NULL 이면t1.id
는 Root 노드이다.- 1에 해당되지 않는 경우, 즉, 부모노드가 존재할 때,
t2.id
NULL이 아니라면t1.id
가 자식노드가 존재한다는 뜻이다. 부모노드도 존재하고, 자식노드도 존재한다면 Inner 노드이다. - 1,2에 해당되지 않는 경우, 즉, 부모노드는 존재하지만 자식노드는 존재하지 않는다면 Leaf 노드이다.
SELECT
-- removal of duplicates
DISTINCT t1.id,
CASE
WHEN t1.p_id IS NULL THEN "Root"
WHEN t2.id IS NOT NULL THEN "Inner"
ELSE "Leaf"
END AS `type`
FROM Tree t1
LEFT JOIN Tree t2 ON t1.id=t2.p_id
-- ordered by id in ascending order.
ORDER BY 1
Lessons learned
CASE 문을 활용해 새로운 변수 만들기
IN Subquery
CASE WHEN d IN (SELECT p_id from Tree) THEN ..
: CASE 문 내에서 IN Subquery- ****MySQL IN subquery 성능, IN sub query는 가급적 사용을 피하자