Notice
Recent Posts
Recent Comments
Link
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

이지은님의 블로그

231202 - SQL 서브쿼리, 그룹화를 이용한 조건에 따른 필터링(GROUP BY, HAVING, WHERE) 본문

TIL

231202 - SQL 서브쿼리, 그룹화를 이용한 조건에 따른 필터링(GROUP BY, HAVING, WHERE)

queenriwon3 2024. 12. 2. 18:37

▷ 오늘 하루 계획

오늘 달리기반 퀘스트를 끝마쳤다. 문제를 몇개 더 풀어보니 나름의 감도 생긴 것 같다. 자바 학습환경은 비주얼 스튜디오 코드에서 진행하면 될 것 같다.

 

 

 

▷ 오늘 배운 것

SELECT CustomerName, 
	sum(Price * Quantity) TotalAmount, 
	count(Quantity) OrderCount
FROM 
(select c.CustomerName, o.Quantity, o.ProductID 
from Orders o join Customers c on o.CustomerID =c.CustomerID
) a JOIN Products p on a.ProductID =p.ProductID 
group by 1
order by 1

서브쿼리를 이용해서 3개의 테이블을 연결하는 방법에 대해 배웠다. JOIN을 +라고, 서브쿼리를 ()라고 치면, (A+B)+C 방법으로 테이블을 연결할 수 있다. 물론 서브 쿼리를 사용하면서 각 쿼리문 마다 select from을 사용하는 것은 필수이다.

 

SELECT p.Category,
	p.ProductName Top_Product,
	sum(o.Quantity) TotalSold
FROM Orders o JOIN Products p ON o.ProductID =p.ProductID 
GROUP BY 1,2
HAVING TotalSold =
	(SELECT MAX(sum_Quantity)
	from 
		(select p2.Category, p2.ProductName, sum(Quantity) sum_Quantity
		from Orders o2 JOIN Products p2 on o2.ProductID =p2.ProductID
		GROUP BY 1,2) a 
	WHERE a.Category = p.Category )

그리고 언제나 해결이 쉽게 안되는 것은 해당부분... 처음에는 join으로 연결한 테이블을 서브쿼리 a로 묶고 그 테이블을 다른 서브쿼리에서 재사용하려고 했지만 생각대로 되진 않았다. 안되는 것을 파악하고 결국에는 join부분을 다시 썼다. 

 

이 문제는 다음과 같이 정리했다.

포인트 1: 각 제품 수량 합의 최고 값을 불러와야하기 때문에 MAX(SUM())이 불가하므로 서브쿼리안에 서브쿼리를 써줘야한다.

포인트 2: 카테고리와 제품을 그룹화 한 것을 2개 만들어줘야한다. 하나는 메인쿼리에서, 하나는 서브 쿼리에서 조건을 줄 때 사용된다.

이런 문제를 계속해서 풀다보니까 where a.category = p.category는 그룹화를 시켜주는 조건문인 것 같다는 가설을 도출했다.

 

 

 

그렇게 생각한 것은 다음코드를 보고 떠올렸는데...

SELECT Name, Department, Salary
FROM Employees e 
WHERE Salary =
	(SELECT max(Salary)
	from Employees e2 
	WHERE e2.Department =e.Department )
ORDER BY 2

각 직원이 속한 부서에서 가장 높은 월급을 받는 직원들만 포함된 결과를 조회하는 SQL 쿼리를 작성해주세요. 라는 문제의 답이다.

"각 직원이 속한 부서의"라는 그룹화를 쓸 것 같은 말이 나왔지만 group by를 사용하지 않았다. 대신 각 부서별이라는 조건은 where e2.Department =e.Department로 지정했다. 특별히 메인쿼리에서 distinct를 사용해서 부서명을 얻은 것도 아닌데, 이 조건문으로 각 부서명을 추출하고 max()를 사용할 수 있는 그룹화가 되었다는 뜻이다. 이를 빠르게 이해하면 난해한 문제에서도 응용할 수 있지 않을까?... 라는 생각을 했다.

 

 

 

▷ 앞으로

SQL퀘스트를 완료했으므로, 예정된 SQL과정은 이걸로 끝내려고 한다. 내일부터는 JAVA관련내용으로 복습해봐야 할 것 같다.