프로그래머스 ORACLE 조건에 맞는 사용자와 총 거래금액 조회하기DB/쿼리 문제풀이2023. 10. 6. 14:57
Table of Contents
오답
SELECT T1.USER_ID, T1.NICKNAME, T1.TOTAL_SALES
FROM (
SELECT B.USER_ID, B.NICKNAME, A.PRICE AS TOTAL_SALES
FROM USED_GOODS_BOARD A
INNER JOIN USED_GOODS_USER B
ON A.WRITER_ID = B.USER_ID
WHERE A.STATUS = 'DONE' --AND A.PRICE >=700000
GROUP BY B.USER_ID, B.NICKNAME, A.PRICE
HAVING A.PRICE >=700000
ORDER BY TOTAL_SALES
) T1
<순서>
- 내부 서브쿼리에서 USED_GOODS_BOARD와 USED_GOODS_USER 테이블을 조인하여 중고 거래 금액이 70만 원 이상인 거래의 정보를 가져옵니다.
- GROUP BY 절에서 사용자 ID, 닉네임, 거래 금액별로 그룹화합니다.
- HAVING 절에서 중고 거래 금액이 70만 원 이상인 그룹만 선택합니다.
- ORDER BY 절에서 거래 금액을 기준으로 정렬합니다.
—>개별 거래 금액이 70만 원 이상인 거래만을 가져오기 때문에, 사용자가 여러 거래를 했더라도 개별 거래 중 하나만 70만 원 이상이면 결과에 나타날 수 있습니다.
정답
-- USED_GOODS_BOARD와 USED_GOODS_USER 테이블에서 완료된 중고 거래의 총금액이 70만 원 이상인 회원
SELECT T1.USER_ID, T1.NICKNAME, SUM(T1.TOTAL_SALES) AS TOTAL_SALES
FROM (
SELECT B.USER_ID, B.NICKNAME, A.PRICE AS TOTAL_SALES
FROM USED_GOODS_BOARD A
INNER JOIN USED_GOODS_USER B
ON A.WRITER_ID = B.USER_ID
WHERE A.STATUS = 'DONE'
) T1
--WHERE TOTAL_SALES >=700000
GROUP BY T1.USER_ID, T1.NICKNAME
HAVING SUM(T1.TOTAL_SALES) >= 700000
ORDER BY TOTAL_SALES;
<순서>
- 내부 서브쿼리에서 USED_GOODS_BOARD와 USED_GOODS_USER 테이블을 조인하여 완료된 중고 거래의 정보를 가져옵니다.
- GROUP BY 절에서 사용자 ID와 닉네임으로 그룹화하고, 해당 그룹의 모든 거래 금액을 합산하여 총 거래 금액을 계산합니다.
- HAVING 절에서 총 거래 금액이 70만 원 이상인 그룹만 선택합니다.
- ORDER BY 절에서 총 거래 금액을 기준으로 정렬합니다.
—>사용자별로 모든 거래 금액을 합산한 후에 HAVING 절에서 필터링하므로, 사용자가 여러 거래를 했을 경우 총 거래 금액이 70만 원 이상이라면 결과에 나타날 수 있습니다
📌서브쿼리에서 안에서 group by 하면 안되는 이유?
서브쿼리에서 집계 함수(SUM)를 사용하여도 가능하지만, 서브쿼리와 메인 쿼리 사이의 관계 때문에 내부적으로 처리 순서가 변경될 수 있습니다.
원래의 쿼리에서는 서브쿼리의 결과에 대해 그룹화된 정보를 계산한 다음 바깥 쿼리에서 다시 그룹화와 집계를 수행하는 것으로 두 번의 그룹화가 발생합니다. 이 경우 쿼리의 복잡성이 높아지며, 최적화된 실행 계획을 만들기 어려울 수 있습니다.+
📌WHERE은 안되고 HAVING은 되는이유?
SQL에서 WHERE 절과 HAVING 절은 조건을 지정하는 데 사용되지만, 조건의 적용 시기와 범위에서 차이가 있습니다.
- WHERE 절: WHERE 절은 쿼리 결과를 필터링하는 데 사용됩니다. WHERE 절에서 지정한 조건은 데이터베이스에서 레코드를 가져올 때 이미 적용되며, 그 결과로서 해당 조건을 만족하는 행들만 선택됩니다. 따라서 WHERE 절에서는 집계 함수를 사용한 결과인 "TOTAL_SALES"를 직접 참조하거나 비교할 수 없습니다. 이는 WHERE 절에서는 집계 함수로 생성된 결과에 접근할 수 없기 때문입니다.
- HAVING 절 HAVING 절은 그룹화된 결과에 대한 조건을 지정하는 데 사용됩니다. GROUP BY 절로 그룹화된 후에 HAVING 절에서 지정한 조건을 만족하는 그룹만을 결과로서 선택합니다. 즉, HAVING 절에서는 집계 함수로 생성된 결과에 접근할 수 있습니다. 따라서 집계 함수로 생성된 "TOTAL_SALES"를 HAVING 절에서 비교하여 필터링할 수 있습니다.
쿼리에서 집계 함수 SUM을 사용하여 TOTAL_SALES를 생성한 후에 이 값을 WHERE 절에서 비교하려 하면 데이터베이스 엔진이 이해하지 못합니다. 하지만 HAVING 절은 집계된 결과에 접근할 수 있기 때문에 HAVING 절에서 비교하는 것이 올바릅니다.
'DB > 쿼리 문제풀이' 카테고리의 다른 글
프로그래머스 ORACLE 카테고리 별 도서 판매량 집계하기 (0) | 2023.10.06 |
---|---|
프로그래머스 ORACLE 식품분류별 가장 비싼 식품의 정보 조회하기 (0) | 2023.10.06 |
프로그래머스 ORACLE 즐겨찾기가 가장 많은 식당 정보 출력하기 (0) | 2023.10.06 |
프로그래머스 ORACLE 자동차 종류 별 특정 옵션이 포함된 자동차 수 구하기 (0) | 2023.10.06 |
프로그래머스 ORACLE 성분으로 구분한 아이스크림 총 주문량 (0) | 2023.10.06 |