본문 바로가기
SQL

[SQL] 데이터분석가 입문 필수 SQL 부트캠프 (12) 서브쿼리: 스칼라 서브쿼리, 테이블 서브쿼리

by 모닥불🔥 2024. 4. 14.

 

이미지 클릭 시 구매 사이트 이동

 

메타코드의 SQL 부트캠프 강의 정리도 끝나간다. 강의는 메타코드 사이트(https://mcode.co.kr/)에서 구매할 수 있다.

글 쓰는 날을 기준으로, 오늘까지 할인한다고 하니 구매해보는 것도 좋을 듯.. 갠적으론 만족스럽게 들었다.


서브쿼리에 대해 배운 내용을 정리하려고 한다. 서브쿼리는 말 그대로 main이 아니라 sub 역할을 한다. 그야말로 SQL의 꽃이라 할 수 있는... 코딩테스트 문제들을 풀다 보면, 중급으로 갈수록 서브쿼리를 정말 많이 사용하는 것 같다(추후에 나오는 with 구문도!).

 

일단 SELECT 구문이 나온 다음에 다시 ()괄호가 나오고 괄호 속에 SELECT ~ 가 들어간다면 무조건 서브쿼리라고 보면 된다. 서브쿼리의 종류로는 스칼라 서브쿼리, 테이블 서브쿼리, 상관 서브쿼리가 있다.

 

🔥 스칼라 서브쿼리

SQL에서 스칼라 서브쿼리는 단일값을 반환한다.

예를 들어, A라는 제품 가격이 제품 가격 평균값보다 크다는 식의 비교 조건을 넣는다고 생각해 보자. 그럴 때 제품 가격의 평균값을 구한 숫자를 넣어 비교하는 게 아니라, 서브쿼리로 바로 계산 후 비교하게 되는 식이다. A 가격 > (제품 가격의 평균에 대한 서브쿼리)

그렇기 때문에 주로 WHERE, HAVING절(조건절)에 사용되며, SELECT 절에서도 자주 사용한다.

SELECT productName, buyPrice
FROM products
WHERE buyprice > (SELECT AVG(buyPrice) FROM products);

 

여기에서 괄호 속에 있는 (SELECT AVG(buyPrice) FROM products) 부분이 서브쿼리이다. 괄호 속에 있는 구문만 떼어서 ;를 붙이고 실행시키면 하나의 결과값이 출력된다.

# 서브쿼리만 실행하기
SELECT AVG(buyPrice) 
FROM products;


🔥 테이블 서브쿼리

스칼라 서브쿼리는 '하나의 값'만을 반환하는 반면, 테이블 서브쿼리는 테이블처럼 행과 열을 반환한다. 일반적으로 SQL문의 FROM 절에서 사용된다. 왜냐, FROM 뒤에 오는 부분이 일반적으로 행과 열로 구성된 테이블이니까..!

 

SELECT customerNumber, order_count
FROM (SELECT 
	customerNumber, COUNT(orderNumber) AS order_count 
	FROM orders 
	GROUP BY customerNumber) AS subquery
WHERE order_count >= 5;

 

테이블 서브쿼리에서도 괄호 속에서 SELECT~ 와 같이 새로운 구문이 시작된다.

# 서브쿼리만 실행하기
SELECT customerNumber, COUNT(orderNumber) AS order_count 
fROM orders GROUP BY customerNumber;

 

괄호 속에 있는 서브쿼리만 실행하면, 결과가 테이블 형태로 나오는 것을 알 수 있다(테이블 서브쿼리).

 

FROM절에 사용한 서브쿼리는 별칭이 필수이다.

진짜 필수인지 궁금해서 별칭 없이 실행해 보면 아래와 같은 경고를 볼 수 있다.

 

문제 1. 최대 주문 개수를 가진 고객의 ID를 조회하세요(orders 테이블에서).

서브쿼리를 이용해서 실습 문제를 풀어보자. 일단... 최대 주문 개수를 가진 고객을 어떻게 구하면 좋을까?

일단, 주어진 테이블부터 살펴보자. 가장 기본적인 SQL 구문을 적어주고...

SELECT *
FROM orders;

 

일단 주문 수를 구하려면... 고객별로, 주문을 몇 번 했는지 카운트 해야겠다. 고객별? 그렇담 GROUP BY를 쓰면 되겠지..?

 

📌 GROUP BY 쉽게 쓰는 법

1) 기준이 되는 값을 gropu by 뒤에 적자(ㅇㅇ별로~)

2) SELECT 절에 같은 값을 적자

3) 원하는 집계 값을 계산하자(예. count, avg, min, max 등)

SELECT customerNumber, COUNT(orderNumber) AS order_count
FROM orders
GROUP BY customerNumber;

 

이러면 고객별 주문 개수가 나온다.

 

우리는 이제 이 테이블을 가지고, MAX값을 계산해야 한다. 이때 필요한 게 서브쿼리! MAX값 하나를 계산하려고 하니까 스칼라 서브쿼리에 해당한다.

SELECT MAX(order_count)
FROM(SELECT customerNumber, COUNT(orderNumber) AS order_count
	FROM orders
	GROUP BY customerNumber) AS subquery;

 

고객별 주문 수 최대값은 26이다. 그러면 이제, 고객별로 주문 횟수를 COUNT하고 그 값이 26인 고객을 찾으면 되겠지?

SELECT customerNumber 
FROM orders 
GROUP BY customerNumber 
HAVING COUNT(orderNumber) = (SELECT MAX(order_count) 
                             FROM (SELECT customerNumber, COUNT(orderNumber) AS order_count 
                                   FROM orders GROUP BY customerNumber) AS subquery);

 

고객 별 주문수 count 값이 26(스칼라 서브쿼리 결과값)와 같은, 즉 주문 수가 가장 많은 고객의 customerNumber(고객번호)를 구하는 쿼리이다.

 

답은 141번 고객님~ 이다. 무려 26번이나 구매해주신 감사한 고객님이군!

 

다음 글에서는 상관 서브쿼리를 설명할 것인데... 상관 서브쿼리는 좀 더 어렵다. ㅎㅠ 그래도 파이팅🔥🔥