SQL 기초 - 서브쿼리

서브쿼리란? 

쿼리속에 존재하는 쿼리로 먼저 수행된 서브쿼리의 값을 이용하여 메인 쿼리를 수행하는데 사용되는 쿼리

SELECT, JOIN, FROM, WHERE절 모두 서브쿼리를 사용할 수 있지만 이용하는 위치에 따라 제약조건이 발생한다. 

SELECT절 서브쿼리 : 1행 1열의 단일값만 사용할 수 있다.

ex) select * from dual <= 이건 안되고, select a from dual <= 이건 가능


JOIN&FROM 절 서브쿼리 : 행과 열에 대한 제약조건은 없지만 반드시 알리아스, 별칭이 필요하다.

ex) (select * from dual) as duals 


WHERE 절 서브쿼리 : 1행 1열 단일 값 또는 N행 1열만 가능하다.

-- 이건 사실 무슨말인지 정확하게 모르겠음;;;


이제 서브쿼리를 이용하여 문제를 풀어보도록 하자 

DB는 기존에 사용했던 가상의 카페 DB를 이용할 예정이다. 

ERD는 아래와 같다. 


문제 1. 음료의 이름 및 가격과 함께 가장 비싼음료와의 가격차이를 조사한다. 조건 : SELECT 절 서브쿼리

select 

  name as 음료 ,

  price as 가격,

  price - (select max(price) from beverages) as 가격차이

from 

beverages ; 



문제2. 주문내역으로 부터 주문별 음료 개수의 평균을 조회하려고 한다. 조건 : from 절 서브쿼리

select 

orderid as 주문번호,

avgcount as 평균주문개수

from 

( select 

order_id as orderid, 

round(avg(count), 1) as avgcount 

from 

order_details 

group by 

order_id) as foo

order by orderid asc ;


문제 3. 주문내역으로 부터 음료 별 주문개수를 조회하려한다. 조건 : join 절 서브쿼리

select 

drink.name,

sum(order_details.count)

from 

order_details

inner join (select 

name, 

id 

from 

beverages ) as drink

on drink.id = order_details.beverage_id 

group by drink.name

order by drink.name asc ; 

빠진 음료가 있어서 inner join이 아닌 right join으로 다시 구해야함을 알았다. 
음료 기준이기 때문에 
select 
drink.name,
coalesce(sum(order_details.count), 0)
from 
order_details
right join (select 
name, 
id 
from 
beverages ) as drink
on drink.id = order_details.beverage_id 
group by drink.name
order by drink.name asc ; 

COALESCE 함수는 오라클에서 사용되는 NVL 함수와 동일한 기능을 한다.


문제 4. 평균 가격보다 비싼 음료를 WHERE 절 서브쿼리를 이용하여 조회하라

select * from beverages

where

price >= (select max(price) from beverages) ; 


다시보니 문제를 잘못이해 했다. 내가 구한건 가장 비싼 음료를 기준으로 했고 문제는 평균보다 비싼음료, 즉, avg를 사용했어야 했다. 

select * from beverages

where

price >= (select avg(price) from beverages) ; 



댓글