SQL 이론
SELECT/FROM
전체칼럼을 실행하는 표시 *(아스테리크)
FROM DB명.테이블명;
- 반드시 속한 DB명과 함께 테이블을 작성해야 함
- 쿼리와 함께 끝에 세미콜론(;)을 붙여줘야 함
- 다수의 SQL문 여러개의 쿼리를 나눠주는 역할 (일부 쿼리만 열고 싶은 경우: 1개의 요청당 1개의 세미콜론)
- 실행하고 싶은 곳에 커서를 둔 채로 ctrl+Enter를 클릭하면 해당 쿼리문만 실행됨
DISTINCT문
- 칼럼 내에 속한 값을 중복없이 불러오기
- SELECT만 사용 가능
- COUNT (DISTINCT 컬럼명) AS 새칼럼명
WHERE절
- 필터링할 조건이 있을 경우
CASE..WHEN
내가 만든 기준에 따라 칼럼을 만들고 싶을 때
- 칼럼은 SELECT에서만 변경할 수 있으므로, SELECT문 뒤에만 위치함
SELECT *,
CASE WHEN 조건식 1 THEN 결과1
WHEN 조건식2 THEN 결과2
ELSE 결과3
END AS 새로운 칼럼명
FROM basic.theglory;
작동 순서(CASE WHEN)
가장 우선순위에서 조건식1 먼저 처리하고 나머지 남은 것들을
조건식2로 처리하면서 순차적으로 필터링되며 처리함
SELECT CAST(나이 AS int) : 데이터 타입 변환
ORDER BY 가장 마지막에 위치함
정렬할 때 ASC, DESC 로 사용
정렬 조건이 두가지 일때, 첫번째부터 순서대로 처리함
첫번째 조건이 똑같은 칼럼은 두번째로 진행
ORDER BY 1 DESC, 4 ASC;
-----------
비교 연산자가 3개 이상일 경우에 일반으로 나열하면 깨진값이 나옴
랜덤 순서로 계산되므로 우선할 부분부터 ()로 설정해주어야 함
IN (정확한 텍스트)
LIKE '%특정 텍스트 포함%'
--------------
sql 문풀
문제 1
음식 종류별 가장 높은 주문 금액과 가장 낮은 주문금액을 조회하고, 가장 낮은 주문금액 순으로 (내림차순) 정렬해봅시다.
select cuisine_type, min(price) min_price, max(price) max_price
from food_orders
group by cuisine_type
order by min_price desc;
문제 2
배달시간이 늦었는지 판단하는 값
주중 : 25분 이상
주말 : 30분 이상
SELECT order_id,
restaurant_name,
day_of_the_week,
delivery_time, -- delivery_time 칼럼 포함
CASE WHEN day_of_the_week='Weekday' AND delivery_time >= 25 THEN 'Late'
WHEN day_of_the_week='Weekend' AND delivery_time >= 30 THEN 'Late'
ELSE 'On-time'
END "지연여부"
FROM food_orders
--------------
<내가 쓴 답안>
select order_id,
restaurant_name,
day_of_the_week,
delivery,
case when (day_of_the_week = 'Weekday') and (delivery_time < 25 ) then 'On-time'
when (day_of_the_week = 'Weekend') and (delivery_time < 30 ) then 'On-time'
else 'Late'
end as "지연여부"
from food_orders;
문제 3
식당별 평균 음식 주문 금액과 주문자의 평균 연령을 기반으로 Segmentation
<내가 푼 답>
select restaurant_name,
case when avg_price <= 5000 then 'price_group1'
when avg_price <= 10000 then 'price_group2'
when avg_price <=50000 then 'price_group3'
else 'price_group4' end as price_group,
case when avg_age < 21 then 'age_group1'
when avg_age <31 then 'age_group2'
when avg_age <41 then 'age_group3'
else 'age_group4' end as age_group
from
(select a. restaurant_name,
avg(a. price) as avg_price,
avg(b.age) as avg_age
from food_orders a inner join customers b on a.customer_id = b.customer_id
group by restaurant_name) as t
order by restaurant_name asc;
-----------
<정답>
select restaurant_name,
case when price <=5000 then 'price_group1'
when price >5000 and price <=10000 then 'price_group2'
when price >10000 and price <=30000 then 'price_group3'
when price >30000 then 'price_group4' end price_group,
case when age <30 then 'age_group1'
when age between 30 and 39 then 'age_group2'
when age between 40 and 49 then 'age_group3'
else 'age_group4' end age_group
from
(
select a.restaurant_name,
avg(price) price,
avg(age) age
from food_orders a inner join customers b on a.customer_id=b.customer_id
group by 1
) t
order by 1
-------------------
음식 타입별, 연령별 주문건수 pivot view 만들어 봅시다. (연령은 10~59세 사이)
select cuisine_type,
max(if(age=20, order_count, 0)) "20대",
max(if(age=30, order_count, 0)) "30대",
max(if(age=40, order_count, 0)) "40대",
max(if(age=50, order_count, 0)) "50대"
from
(
select cuisine_type,
case when age between 10 and 19 then 10
when age between 20 and 29 then 20
when age between 30 and 39 then 30
when age between 40 AND 49 then 40
else 50 end as age_group,
count(*) as order_count
from food_orders f inner join customers c on f.customer_id = c.customer_id
group by cuisine_type,
case when age between 10 and 19 then 10
when age between 20 and 29 then 20
when age between 30 and 39 then 30
when age between 40 AND 49 then 40
else 50 end as age_group,
group by cuisine_type;
댓글 영역