이 문제는 단순히 중복 데이터를 찾는 것이 아니라,
중복된 채용 공고를 올린 회사 수(company_id 기준) 를 구하는 문제이다.
중복의 정의는 다음과 같다.
이 세 가지가 모두 동일한 경우를 중복으로 본다.
처음에는 다음과 같은 방식으로 문제를 해결했다.
select count(cnt) as duplicate_companies
from
(
SELECT count(company_id) as cnt, title, description
FROM job_listings
group by company_id, title, description
) a
where cnt > 1;
이 접근 자체는 중복을 찾는 방식으로는 올바른 방향이겠지만 최종적으로는 접근 방법이 틀렸다.
문제는 마지막 집계 부분이였다.
count(cnt)
이 쿼리는 다음을 의미한다.
하지만 문제에서 요구하는 것은
즉, 집계 대상이 다르다는 점이다. 문제는 통과했지만 테스트케이스가 많이 존재 했다면 실패했을 것이다.
다음과 같은 데이터가 있다고 가정했을 때
| company_id | title | description | count |
|---|---|---|---|
| 1 | A | X | 2 |
| 1 | B | Y | 2 |
이 경우는
count(cnt) = 2
중복 건수 기준으로 계산될 것이다.
COUNT(DISTINCT company_id) = 1
실제로는 회사 수 기준으로 계산되어야 하기 때문에 1이라는 값이 계산될 것이다.
이 문제에서 가장 중요한 포인트는 다음이다.
중간 결과는 "중복된 공고 목록"이다.
하지만 최종 결과는 "그 공고를 가진 회사 수"이다.
즉,
최종적으로 아래와 같이 수정하였다.
select count(DISTINCT company_id) as duplicate_companies
from
(
SELECT count(*), company_id, title, description
FROM job_listings
GROUP BY company_id, title, description
HAVING count(*) > 1
) a;
GROUP BY company_id, title, description
HAVING count(*) > 1
COUNT(DISTINCT company_id)
문제에서는 "회사 수"를 구해야 했기 때문에 DISTINCT가 필요했다.
중복된 공고 목록
중복 공고를 가진 회사 수
이 두 개를 혼동하면서 문제가 발생했다.
GROUP BY를 사용하면 데이터가 "그룹 단위"로 바뀐다.
하지만 이후 COUNT를 할 때
이 부분을 반드시 구분해야 될 것 같다.
이 문제는 다음 패턴으로 정리할 수 있다.
GROUP BY A, B, C
HAVING COUNT(*) > 1
-> DISTINCT A
-> COUNT