본문 바로가기
Programming/SQL

[프로그래머스 SQL] 조건에 맞는 사용자 정보 조회하기

by 용스토리랜드 2024. 7. 8.

✅ 문제 설명

USED_GOODS_BOARD와 USED_GOODS_USER 테이블에서 중고 거래 게시물을 3건 이상 등록한 사용자의 사용자 ID, 닉네임, 전체주소, 전화번호를 조회하는 SQL문을 작성해주세요. 이때, 전체 주소는 시, 도로명 주소, 상세 주소가 함께 출력되도록 해주시고, 전화번호의 경우 xxx-xxxx-xxxx 같은 형태로 하이픈 문자열(-)을 삽입하여 출력해주세요. 결과는 회원 ID를 기준으로 내림차순 정렬해주세요.

 

✅ 예시

 

✅ 나의 정답 코드

<설명>

  • USED_GOODS_BOARD와 USED_GOODS_USER 테이블을 WRITER_ID와 USER_ID를 기준으로 LEFT JOIN 합니다.
  • CITY, STREET_ADDRESS1, STREET_ADDRESS2를 결합 (CONCAT)해 전체주소, TLNO를 하이픈으로 구분(SUBSTR + CONCAT)해 전화번호를 생성합니다.
  • WRITER_ID별로 게시물 수를 계산(COUNT)하고, 이를 USER_COUNT로 저장합니다.
  • 서브쿼리에서 USER_COUNT가 2보다 큰 사용자만 필터링하고, 외부 쿼리에서 필요한 열을 선택합니다.
  • 결과를 USER_ID 기준으로 내림차순 정렬합니다.
#<< SUBQUERY 사용 >>
SELECT USER_ID, NICKNAME, 전체주소, 전화번호
FROM
(SELECT 
    WRITER_ID AS USER_ID,
    NICKNAME,
    CONCAT(CITY, ' ', STREET_ADDRESS1, ' ', STREET_ADDRESS2) AS 전체주소,
    CONCAT(SUBSTR(TLNO, 1, 3), '-', SUBSTR(TLNO, 4, 4), '-', SUBSTR(TLNO, 8, 4)) AS 전화번호,
    COUNT(*) AS USER_COUNT
FROM USED_GOODS_BOARD B LEFT JOIN USED_GOODS_USER U ON B.WRITER_ID = U.USER_ID
GROUP BY WRITER_ID) SUB
WHERE USER_COUNT > 2
ORDER BY USER_ID DESC

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

 


 

✅ HAVING 절 대신 서브쿼리와 WHERE 절을 사용한 이유 

 

  • 가독성: 서브쿼리를 사용하면 쿼리를 논리적인 블록으로 나눌 수 있어 가독성이 높아집니다.
  • 성능 최적화: 일부 데이터베이스 시스템에서 서브쿼리와 WHERE 절 조합이 HAVING 절보다 더 효율적으로 실행될 수 있습니다.
  • 복잡한 조건 처리: 서브쿼리 내에서 복잡한 계산이나 변형을 수행하고, 외부 쿼리에서 간단히 필터링 조건을 적용할 수 있습니다.

 

  • CONCAT:
    • 여러 문자열을 결합합니다.
    • 예: CONCAT(CITY, ' ', STREET_ADDRESS1, ' ', STREET_ADDRESS2).
  • SUBSTR:
    • 문자열의 일부를 추출합니다.
    • 예: SUBSTR(TLNO, 1, 3).

# <참고>

기본키와 외래키 관계에 따른 JOIN 사용:

  • 기본키와 외래키 관계를 통해 테이블 간의 관계를 정의합니다.
  • LEFT JOIN: 외래키 관계가 있는 테이블에서 기본키 테이블의 모든 레코드를 포함하고, 외래키 테이블에 없는 값은 NULL로 표시합니다.
  • INNER JOIN: 외래키 테이블에서 기본키 테이블과 일치하는 레코드만 포함합니다.

 

 

반응형