조건에 맞는 사용자 정보 조회하기 (SUBSTRING, CONCAT, HAVING)

창하쿠·2025년 6월 5일

sql questions

목록 보기
6/7

🚩 문제 개요

이번 문제는 USED_GOODS_USER (사용자 테이블), USED_GOODS_BOARD (게시판 테이블)를 활용하여 다음 정보를 조회하는 것이다:

게시글 3건 이상 등록한 사용자
USER_ID, NICKNAME, 전체주소, 전화번호 출력

조건은 다음과 같다:

  • 📞 전화번호'xxx-xxxx-xxxx' 형식으로 출력
  • 🏠 전체주소시 + 도로명 주소 + 상세주소를 공백 포함하여 출력
  • 결과는 USER_ID 기준으로 내림차순 정렬

✂️ SUBSTRING 함수

SUBSTRING 함수는 문자열에서 원하는 구간을 잘라내는 함수이다.

SUBSTRING(문자열, 시작위치, 길이)

예시:

SUBSTRING('01053422914', 1, 3)'010'
SUBSTRING('01053422914', 4, 4)'5342'
SUBSTRING('01053422914', 8, 4)'2914'

이번 문제에서는 전화번호가 숫자만 저장되어 있기 때문에, 이를 'xxx-xxxx-xxxx' 형식으로 출력하기 위해 SUBSTRING을 사용하였다.


🔗 CONCAT 함수

CONCAT 함수는 여러 문자열을 하나로 이어붙이는 함수이다.

CONCAT(문자열1, 문자열2, ...)

예시:

CONCAT('Hello', ' ', 'World')'Hello World'

이번 문제에서는 주소를 출력할 때 시 + 도로명 주소 + 상세주소를 공백 포함하여 자연스럽게 이어붙이기 위해 사용하였다:

CONCAT(U.CITY, ' ', U.STREET_ADDRESS1, ' ', U.STREET_ADDRESS2)

만약 ' ' (공백)을 넣지 않으면 주소가 붙어서 출력되므로 주의가 필요하다. ⚠️


🔍 HAVING 절

HAVING 절은 GROUP BY 이후에 그룹핑된 결과에 대해 조건을 걸 때 사용한다.

WHERE vs HAVING 차이

구문사용 시점
WHERE그룹핑 전 (행 필터링)
HAVING그룹핑 후 (그룹 결과 필터링)

이번 문제에서는 작성자별로 게시글 수를 집계한 뒤, 게시글이 3건 이상인 사용자만 필터링하기 위해 HAVING 절을 사용하였다:

HAVING COUNT(B.WRITER_ID) >= 3

중요한 점은 WHERE 절에서는 COUNT()와 같은 집계 함수를 사용할 수 없다는 점이다. ⚠️
집계 함수는 반드시 GROUP BY 이후 결과에서만 계산되므로 HAVING 절을 통해 필터링해야 한다.


🎁 최종 쿼리

SELECT
    U.USER_ID,
    U.NICKNAME,
    CONCAT(U.CITY, ' ', U.STREET_ADDRESS1, ' ', U.STREET_ADDRESS2) AS 전체주소,
    CONCAT(
        SUBSTRING(U.TLNO, 1, 3), '-', 
        SUBSTRING(U.TLNO, 4, 4), '-', 
        SUBSTRING(U.TLNO, 8, 4)
    ) AS 전화번호
FROM USED_GOODS_USER U
JOIN USED_GOODS_BOARD B
ON U.USER_ID = B.WRITER_ID
GROUP BY U.USER_ID
HAVING COUNT(B.WRITER_ID) >= 3
ORDER BY U.USER_ID DESC;

📝 정리

  • SUBSTRING 함수를 이용해 전화번호를 'xxx-xxxx-xxxx' 형식으로 가공하였다.
  • CONCAT 함수를 이용해 주소 문자열을 자연스럽게 이어붙였다.
  • GROUP BY 를 통해 작성자별 그룹을 만들고, HAVING 절을 통해 게시글 수가 3건 이상인 사용자만 필터링하였다.
  • WHERE 절은 그룹핑 이전 필터링에 사용하는 반면, HAVING 절은 그룹핑 이후 집계 결과에 조건을 걸 때 사용한다는 점을 반드시 기억할 필요가 있다.
profile
아무것도 모르는 아무개

0개의 댓글