[MySQL][Lv. 3] 대장균들의 자식의 수 구하기 ✨

드코미·2025년 5월 3일
post-thumbnail

1. 문제 접근

1-1. LEFT JOIN

이 문제에서는 그냥 JOIN(=INNER JOIN)을 하면 안되고, LEFT JOIN을 해야한다.

그 이유는 자식이 없는 부모도 결과에 포함되어야하기 때문이다.

2. 풀이

내가 쓴 풀이 (이것도 맞긴 함)

SELECT A.ID, IFNULL(COUNT(B.ID), 0) AS CHILD_COUNT
FROM ECOLI_DATA A
LEFT JOIN ECOLI_DATA B
    ON A.ID = B.PARENT_ID
GROUP BY A.ID
ORDER BY A.ID;

정답 풀이 (출처)

SELECT 
    P.ID
    , COUNT(C.ID) AS CHILD_COUNT 
FROM ECOLI_DATA AS P
    LEFT JOIN ECOLI_DATA AS C
    ON P.ID = C.PARENT_ID
GROUP BY ID
ORDER BY ID

정답 풀이와 비교하다보니, 몇가지 궁금한 점이 생겼다.

2-1. 정답 풀이에서는 GROUP BY랑 ORDER BY에서 그냥 ID라고 적었는데, 나는 A.ID라고 명시를 해줬다. 굳이 명시를 안해도 되는건지?

나는 명시를 꼭 해야한다고 생각해서 명시했는데, 굳이 명시를 안해도 되는건지 궁금해졌다.

SELECT *
FROM ECOLI_DATA A
LEFT JOIN ECOLI_DATA B
    ON A.ID = B.PARENT_ID;

이렇게 출력을 해보면 결과는 다음과 같이 나온다.

JOIN을 먼저 진행한 테이블에 GROUP BY랑 ORDER BY가 진행될텐데, 위에서처럼 JOIN된 테이블에는 ID 컬럼이 2개가 발생한다.

그래서 나는 어떤 ID인지 구분을 당연히 해줘야한다고 생각했다.

✔️ SQL은 우선적으로 SELECT 절에서 지정한 ID 기준으로 해석한다.

SELECT A.ID, COUNT(B.ID)
FROM ECOLI_DATA A
LEFT JOIN ECOLI_DATA B
  ON A.ID = B.PARENT_ID
GROUP BY ID

코드가 이럴 때, A.IDB.ID 둘 다 있지만, 사실 B.IDCOUNT와 함께 쓰였기 때문에, ID이름으로 표시되는 건 A.ID밖에 없다.

따라서 SQL은 GROUP BYORDER BY를 수행할 때, "아, SELECT된 ID가 A.ID였네?"라고 자동으로 추론한다. 그래서 굳이 A라고 명시해주지 않아도, A.ID로 추론하고 진행한다.

반면에

SELECT A.ID, B.ID
FROM ECOLI_DATA A
JOIN ECOLI_DATA B ON ...
GROUP BY ID

이렇게 A.IDB.ID 모두 SELECT절에 등장하면, 이 경우에는 ID가 누구 건지 애매해진다. 따라서 이 경우 SQL은 에러를 낸다(ambiguous column name 'ID').

2-2. 정답 풀이에서는 IFNULL을 사용하지 않았다. 왜지?

그 이유는 이미

SELECT A.ID, COUNT(B.ID) AS CHILD_COUNT
FROM ECOLI_DATA A
LEFT JOIN ECOLI_DATA B
    ON A.ID = B.PARENT_ID
GROUP BY A.ID
ORDER BY A.ID;

여기서 COUNT를 진행할 때, COUNT시, NULL값은 무시하고 개수를 세기 때문에,

값이 NULL 밖에 없다면 0으로 집계되지, 결과가 절대 NULL이 나올수가 없다.

profile
할 수 있다!!!

0개의 댓글