DB/쿼리 문제풀이

프로그래머스 ORACLE 조건에 맞는 사용자와 총 거래금액 조회하기

sshhhh 2023. 10. 6.

오답

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

 

<순서>

  1. 내부 서브쿼리에서 USED_GOODS_BOARD와 USED_GOODS_USER 테이블을 조인하여 중고 거래 금액이 70만 원 이상인 거래의 정보를 가져옵니다.
  2. GROUP BY 절에서 사용자 ID, 닉네임, 거래 금액별로 그룹화합니다.
  3. HAVING 절에서 중고 거래 금액이 70만 원 이상인 그룹만 선택합니다.
  4. 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;

 

<순서>

  1. 내부 서브쿼리에서 USED_GOODS_BOARD와 USED_GOODS_USER 테이블을 조인하여 완료된 중고 거래의 정보를 가져옵니다.
  2. GROUP BY 절에서 사용자 ID와 닉네임으로 그룹화하고, 해당 그룹의 모든 거래 금액을 합산하여 총 거래 금액을 계산합니다.
  3. HAVING 절에서 총 거래 금액이 70만 원 이상인 그룹만 선택합니다.
  4. 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 절에서 비교하는 것이 올바릅니다.

댓글