
문제
https://school.programmers.co.kr/learn/courses/30/lessons/164670
프로그래머스
SW개발자를 위한 평가, 교육의 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프
programmers.co.kr
- USED_GOODS_BOARD와 USED_GOODS_USER 테이블에서 중고 거래 게시물을 3건 이상 등록한 사용자의 사용자 ID, 닉네임, 전체주소, 전화번호를 조회하는 SQL문을 작성
- 이때, 전체 주소는 시, 도로명 주소, 상세 주소가 함께 출력되도록 하기
- 전화번호의 경우 xxx-xxxx-xxxx 같은 형태로 하이픈 문자열(-)을 삽입하여 출력
- 결과는 회원 ID를 기준으로 내림차순 정렬
문제 설명
- 중고 거래 게시판 정보를 담은 USED_GOODS_BOARD 테이블
- 중고 거래 게시판 첨부파일 정보를 담은 USED_GOODS_USER 테이블
정답 코드
SELECT U.USER_ID,
U.NICKNAME,
CONCAT(U.CITY, ' ', U.STREET_ADDRESS1, ' ', U.STREET_ADDRESS2) 전체주소,
CONCAT(SUBSTR(U.TLNO,1,3),'-', SUBSTR(U.TLNO,4,4), '-', SUBSTR(U.TLNO,8,4)) 전화번호
FROM USED_GOODS_USER U JOIN
(SELECT WRITER_ID
FROM USED_GOODS_BOARD
GROUP BY WRITER_ID
HAVING COUNT(*)>=3
)B ON U.USER_ID = B.WRITER_ID
ORDER BY U.USER_ID DESC
코드 설명
1. 서브쿼리
SELECT WRITER_ID
FROM USED_GOODS_BOARD
GROUP BY WRITER_ID
HAVING COUNT(*)>=3
- USED_GOODS_BOARD에서 작성자(WRITER_ID)별로 게시글 수를 그룹화
- 게시글이 3건 이상인 사용자만 선별
2. 메인 쿼리
- 서브쿼리 결과와 USED_GOODS_USER 테이블을 JOIN하여 사용자 정보를 가져옴
- 조건: U.USER_ID = WRITER_ID
3. SELECT절
- USER_ID
- NICKNAME
- 전체주소
- CITY, STREET_ADDRESS1, STREET_ADDRESS2를 공백으로 연결해 출력
-
CONCAT(U.CITY, ' ', U.STREET_ADDRESS1, ' ', U.STREET_ADDRESS2)
- 전화번호
- TLNO를 010-1234-5678 형태로 가공
- CONCAT(SUBSTR(U.TLNO,1,3), '-', SUBSTR(U.TLNO,4,4), '-', SUBSTR(U.TLNO,8,4))
4. 정렬
- ORDER BY U.USER_ID DESC
- 사용자 ID를 기준으로 내림차순 정렬
첫 번째 시도 (실패. 오류)
SELECT U.USER_ID,
U.NICKNAME,
(U.CITY+U.STREET_ADDRESS1+U.STREET_ADDRESS2) 전체주소,
CONCAT(U.TLNO[:2],'-', U.TLNO[3:6], '-', U.TLNO[7:], '-') 전화번호
FROM USED_GOODS_BOARD B JOIN USED_GOODS_USER U ON B.WRITER_ID = U.USER_ID
WHERE COUNT(B.WRITER_ID)>=3
오류 이유
- (U.CITY+U.STREET_ADDRESS1+U.STREET_ADDRESS2)
- `+ 연산자`는 숫자 덧셈 (문자열을 붙이려면 CONCAT() 사용)
- CONCAT(U.TLNO[:2],'-', U.TLNO[3:6], '-', U.TLNO[7:], '-')
- Python 인덱싱 (Python이랑 같이 하면서 헷갈리지 말기!!)
- SQL에서는 SUBSTR() 또는 LEFT/RIGHT/MID 등을 사용
- WHERE 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) 전체주소,
CONCAT(SUBSTR(U.TLNO,1,3),'-', SUBSTR(U.TLNO,4,4), '-', SUBSTR(U.TLNO,8,4)) 전화번호
FROM USED_GOODS_BOARD B JOIN USED_GOODS_USER U ON B.WRITER_ID = U.USER_ID
GROUP BY U.USER_ID, U.NICKNAME
HAVING COUNT(U.USER_ID)>=3
틀린 이유
- CONCAT(...)도 GROUP BY에 포함해야 함 (집계함수가 아니므로)
- GROUP BY절에 포함하거나
- GROUP BY 쓰지 않고 서브쿼리 활용
- 내림차수 정렬 잊지말고 추가하기
세 번째 시도 (성공)
SELECT U.USER_ID,
U.NICKNAME,
CONCAT(U.CITY, ' ', U.STREET_ADDRESS1, ' ', U.STREET_ADDRESS2) 전체주소,
CONCAT(SUBSTR(U.TLNO,1,3),'-', SUBSTR(U.TLNO,4,4), '-', SUBSTR(U.TLNO,8,4)) 전화번호
FROM USED_GOODS_USER U JOIN
(SELECT WRITER_ID
FROM USED_GOODS_BOARD
GROUP BY WRITER_ID
HAVING COUNT(*)>=3
)B ON U.USER_ID = B.WRITER_ID
ORDER BY U.USER_ID DESC
- 참고) MySQL에서는 SUBSTR()과 SUBSTRING()이 같지만, 협업 시 SUBSTRING() 선호할 수 있음
'코딩 테스트 연습 > [프로그래머스][리트코드] MySQL' 카테고리의 다른 글
| [LV.4] String, Date > 조건에 부합하는 중고거래 상태 조회하기 (0) | 2025.06.24 |
|---|---|
| [LV.4] String, Date > 특정 옵션이 포함된 자동차 리스트 구하기 (3) | 2025.06.23 |
| [LV.4] SUM, MAX, MIN > 최댓값 구하기 (0) | 2025.06.19 |
| [LV.4] 재구매가 일어난 상품과 회원 리스트 구하기 (1) | 2025.06.18 |
| [LV.4] SELECT > 과일로 만든 아이스크림 고르기 (2) | 2025.06.17 |