1. 문제 출처

https://school.programmers.co.kr/learn/courses/30/lessons/164670

2. 문의 의도

  • 서브쿼리를 이용한 행 필터링

3. 풀이

  • 오답
SELECT B.WRITER_ID AS USER_ID, 
U.NICKNAME, CONCAT(U.STREET_ADDRESS1," ",U.STREET_ADDRESS2) AS 전체주소, 
CONCAT(SUBSTR(U.TLNO,1,3),"-",SUBSTR(U.TLNO,4,4),"-",SUBSTR(U.TLNO,8,4)) AS 전화번호
FROM USED_GOODS_BOARD AS B JOIN USED_GOODS_USER AS U ON B.WRITER_ID=U.USER_ID
GROUP BY B.WRITER_ID
HAVING COUNT(*) >= 3
ORDER BY B.WRITER_ID DESC
  • 정답
select distinct(u.USER_ID), u.NICKNAME, 
       concat(CITY,' ',STREET_ADDRESS1,' ',STREET_ADDRESS2) as 전체주소, 
       concat(left(TLNO,3),'-',substr(TLNO,4,4),'-',right(TLNO,4)) as 전화번호
from USED_GOODS_BOARD as b
join USED_GOODS_USER as u on b.WRITER_ID = u.USER_ID
where b.WRITER_ID in (select WRITER_ID 
                     from USED_GOODS_BOARD
                     group by WRITER_ID
                     having count(WRITER_ID) >= 3)
order by user_id desc

 

위 오답과 정답 둘 다 예시 테이블에서는 적어도 같은 테이블로 출력된다. 하지만 채점하면 에러가 난다.  그 이유는 프로그래머스에서 채점하는 테이블이 예시 테이블이 아닌 채점 테이블이 따로 있기 때문이다. 오답의 경우 두 테이블을 조인하여 having count(*)을 이용하여 필터링을 했는데 다음과 같은 상황에 엣지 케이스가 있다.

"동일한 유저가 판매글을 2개 올리고, 주소가 2개 인 경우" 이 경우 문제에 따르면 중고 거래 게시물을 3건 이상 등록한 것이 아닌 2건이지만 오답처럼 join과정에서 4개로 뻥튀기되고 count(*)로 집계하는 과정에서 의도치 않은 필터링이 된다. 따라서 정답처럼 사전에 서브쿼리로 writer_id를 선별해놓고 필터링 하는게 적절하다고 할 수 있겠다.

인 오류도 생각할 수 있으나.. 그냥 오답에 CITY 컬럼이 누락됐다. 너무 복잡하게 생각했네 🤣

+ Recent posts