프로그래머스 SQL 고득점 Kit
https://school.programmers.co.kr/learn/challenges?tab=sql_practice_kit
동물 보호소에 들어온 동물 이름 중 두 번 이상 쓰인 이름과 해당 이름이 쓰인 횟수를 조회하는 SQL문을 작성해주세요.
이때 결과는 이름이 없는 동물은 집계에서 제외하며, 결과는 이름 순으로 조회해주세요.
SELECT
NAME,
COUNT(*) AS COUNT
FROM ANIMAL_INS
GROUP BY NAME
HAVING
COUNT(*) >= 2
AND NAME IS NOT NULL
AND TRIM(NAME) <> ''
ORDER BY NAME;
처음에 작성한 쿼리는 다음과 같다.
SELECT NAME,
COUNT(*) AS COUNT
FROM ANIMAL_INS
GROUP BY NAME
HAVING NAME IS NOT NULL
ORDER BY NAME;
그런데 한번 사용된 이름만 나와서 잘못된 쿼리라는 것을 깨달았다.
따라서 HAVING
절에 다음의 조건들을 추가하였다.
- 2회 이상인 결과만 출력
- 빈 문자열/공백만인 이름 제외
사실 HAVING NAME IS NOT NULL
이라는 조건에 의해서 2회 이상인 결과값도 출력되어야 하는 것은 이론적으로 옳다. 하지만 왜 출력이 되지 않았을까?
출력이 되지 않은 이유는 다음과 같이 추론할 수 있다.
공백 문제: "Lucy" vs "Lucy " → 다른 값으로 그룹됨
대소문자/콜레이션: "Lucy" vs "lucy" → 환경에 따라 다른 그룹
빈 문자열: ''(빈 문자열)은 NULL이 아니라서 그룹에 섞임
보이지 않는 문자: 비가시 공백/유니코드(normalization) 차이 등
정규화 후 그룹핑: TRIM()으로 앞뒤 공백 제거, LOWER()(또는 UPPER())로 대소문자 통일
→ 이 정규화된 값으로 GROUP BY
이름 없음 제외 강화: NAME IS NOT NULL + TRIM(NAME) <> ''
진짜 중복만 보기: HAVING COUNT(*) >= 2