여러 번의 연산을 한 번의 SQL 문으로 수행하기
select column1, special_column
from
( /* subquery */
select column1, column2 special_column
from table1
) a
select column1, column2
from table1
where column1 = (select col1 from table2)
select order_id, restaurant_name, if(over_time>=0, over_time, 0) over_time
from
(
select order_id, restaurant_name, food_preparation_time-25 over_time
from food_orders
) a
// 음식 주문시간 - 25 했을 때, 25분보다 작은 결과가 있을 수도 있음
// -> 더 작은 경우는 0으로 출력하기 위해 if문 적용
select restaurant_name,
price_per_plate*ratio_of_add "수수료"
from
(
select restaurant_name,
case when price_per_plate<5000 then 0.005
when price_per_plate between 5000 and 19999 then 0.01
when price_per_plate between 20000 and 29999 then 0.02
else 0.03 end ratio_of_add,
price_per_plate
from
(
select restaurant_name, avg(price/quantity) price_per_plate
from food_orders
group by 1
) a
) b
오답
SELECT addr,
case when delivery_time > 30 then delivery_time/QUALIFY "30분 초과"
when delivery > 20 then delivery_time/QUALIFY "20분에서 30분"
else delivery_time/QUALIFY end "10분에서 20분"
from (select addr, delivery_time, quantity
from food_orders
group by 1) a
// ❌ subquery 안에 delivery_tiem, quantity를 따로 놓고 거기서 갖다 쓰려하니까 에러가 났다.
// 이 둘을 미리 avgerage 구해놓고, 그걸 가지고 이름 붙여줘야 하는 거였다.
해답
select restaurant_name,
sido,
case when avg_time<=20 then '<=20'
when avg_time>20 and avg_time <=30 then '20<x<=30'
when avg_time>30 then '>30' end time_segment
from
(
select restaurant_name,
substring(addr, 1, 2) sido,
avg(delivery_time) avg_time
from food_orders
group by 1, 2
) a
음식점의 총 주문수량과 주문 금액을 연산하고, 주문 수량을 기반으로 수수료 할인율 구하기
(할인조건
수량이 5개 이하 → 10%
수량이 15개 초과, 총 주문금액이 300000 이상 → 0.5%
이 외에는 일괄 1%)
SELECT restaurant_name,
total_quantity,
total_price,
case when total_quantity <= 5 then 0.1
when total_quantity > 15 and total_price >= 300000 then 0.005
else 0.01 end rate
from
(
SELECT restaurant_name ,
sum(quantity) total_quantity,
sum(price) total_price
from food_orders
group by 1
)
SQL Error [1248] [42000]: Every derived table must have its own alias
모든 열이 있어야 된다고...? 어떻게 해결하지
-> then 뒤에 '열 이름'이 와야됐는데, 출력되는 값을 지정해주는 걸로 착각했던 것이다.
-> 값은 원래 있던게 출력되는거고,해당하는 열의 이름을 지정해주도록 해보자!
SELECT restaurant_name,
total_quantity,
total_price,
case when total_quantity <= 5 then '10%'
when total_quantity > 15 and total_price >= 300000 then '0.5%'
else '1%' end rate
from
(
SELECT restaurant_name ,
sum(quantity) total_quantity,
sum(price) total_price
from food_orders
group by 1
)
또 똑같은 에러 메시지가 떴다...
- 에러메시지 :
SQL Error [1248] [42000]: Every derived table must have its own alias
- 뜻 : 파생 테이블(즉, 서브쿼리)에 별칭(alias)을 부여해야 한다!
select restaurant_name,
case when sum_of_quantity<=5 then 0.1
when sum_of_quantity>15 and sum_of_price>=300000 then 0.005
else 0.01 end ratio_of_add
from
(
select restaurant_name,
sum(quantity) sum_of_quantity,
sum(price) sum_of_price
from food_orders
group by 1
) a
벤다이어그램 생각해보기!
-- LEFT JOIN
select 조회 할 컬럼
from 테이블1 a left join 테이블2 b on a.공통컬럼명=b.공통컬럼명
-- INNER JOIN
select 조회 할 컬럼
from 테이블1 a inner join 테이블2 b on a.공통컬럼명=b.공통컬럼명
SELECT *
from food_orders left join payments on food_orders.order_id = payments.order_id
- food_orders 와 payments 두 테이블을 join할 예정
- 벤다이어그램의 A 테이블은 food_orders, B 테이블은 payments가 된다고 생각하기
- 두 테이블에서 겹치는 열 : order_id
- payments에는 order_id의 값이 없더라도 food_orders 테이블은 전부 다 보여줄 것 (left join)
- 겹치는 열 order_id를 지정해주는 구문
on
select a.order_id,
a.customer_id,
a.restaurant_name,
a.price,
b.name,
b.age,
b.gender
from food_orders a left join customers b on a.customer_id=b.customer_id
두 테이블에도 별칭을 지어줄 수 있다! (여기서는 a, b라고 지어준 것)