SELECT
FROM
WHERE
GROUP BY
ORDER BY
→ 문자 데이터의 형태를 바꿔 Query 결과를 바로 사용할 수 있도록 해결
SELECT restaurant_name "기존 상점명",
REPLACE(restaurant_name, 'Blue', 'Pink') "바뀐 상점명"
FROM food_orders
WHERE restaurant_name LIKE '%Blue Ribbon%'
SELECT addr "기존 주소",
REPLACE(addr, '곡', '가') "바뀐 주소"
FROM food_orders
WHERE addr LIKE '%문곡리%'
SELECT addr "기존 주소",
SUBSTR(addr, 1, 2) "시도"
FROM food_orders
WHERE addr LIKE '%서울특별시%'
SELECT restaurant_name "기존 상호",
addr "기존 주소",
CONCAT('[', SUBSTR(addr, 1, 2), '] ', restaurant_name) "바뀐 상호"
FROM food_orders
WHERE addr LIKE '%서울특별시%'
a. 어떤 테이블에서 → FROM food_orders
b. 어떤 컬럼 → price, cuisine_type, addr
c. 어떤 조건 → WHERE addr LIKE ‘%서울특별시%’
d. 어떤 함수(수식) → AVG(price), SUBSTR(addr, 1, 2)
SELECT SUBSTR(addr, 1, 2) as "시도",
cuisine_type as "타입",
AVG(price) as "평균 금액"
FROM food_orders
WHERE addr LIKE '서울%'
GROUP BY SUBSTR(addr, 1, 2), cuisine_type
💡 조회할(범주를 묶어줄) 컬럼의 위치를 적어서 GROUP BY를 명명해줄 수 있다:
위의 예시에서
column1 = SUBSTR(addr, 1, 2) as *"시도" ,
column2 = cuisine_type as "타입",
column3 = AVG(price) as "평균 금액" 이므로
GROUP BY SUBSTR(addr, 1, 2), cuisine_type을 GROUP BY 1, 2라 적을 수 있음
SELECT SUBSTR(email,10) "도메인",
COUNT(1) "고객 수",
AVG(age) "평균 연령"
FROM customers
GROUP BY 1
💡 SUBSTR(email, 10)이 마음에 안 들어서 좀 더 찾아봤음
→ 구분자를 이용해 문자열을 잘라오는 함수 SUBSTRING_INDEX
SUBSTRING_INDEX(email, '@', -1)
→ 돌려봤더니 실습 데이터에는 at symbol이 없는 메일 주소가 있어서 예쁘게는 안 나옴
SELECT CONCAT('[', SUBSTR(addr, 1, 2), '] ', restaurant_name, ' (' ,cuisine_type, ')') "바뀐이름",
COUNT(1) "주문건수"
FROM food_orders
GROUP BY 1
IF(condition, value_if_true, value_if_false)
SELECT restaurant_name,
cuisine_type "원래 음식 타입",
IF(cuisine_type='Korean', '한식', '기타') "음식 타입"
FROM food_orders
SELECT addr "원래 주소",
IF(addr LIKE '%평택%', REPLACE(addr, '문곡리', '문가리'), addr) "바뀐 주소"
FROM food_orders
WHERE addr LIKE '%문곡리%'
SELECT SUBSTRING_INDEX(IF(email LIKE '%gmail%', REPLACE(email, 'gmail', '@gmail'), email), '@', -1) "이메일 도메인",
COUNT(customer_id) "고객 수",
AVG(age) "평균 연령"
FROM customers
GROUP BY 1
CASE
WHEN condition1 THEN result1
WHEN condition2 THEN result2
WHEN conditionN THEN resultN
ELSE result
END;
SELECT restaurant_name,
cuisine_type "원래 음식 타입",
CASE
WHEN cuisine_type='Korean' THEN '한식'
WHEN (cuisine_type='Japanese' OR cuisine_type = 'Chinese') THEN '아시아'
ELSE '기타'
END AS "음식 타입"
FROM food_orders
💡 WHEN cuisine_type IN (’Japanese’, ‘Chinese’) THEN ‘아시아’
SELECT order_id,
price,
quantity,
CASE
WHEN quantity = 1 THEN price
WHEN quantity >= 2 THEN price/quantity
END AS "음식 단가"
FROM food_orders
💡 IF로도 쓸 수 있음!
SELECT order_id,
price,
quantity,
IF(quantity = 1, price, price/quantity) "음식 단가"
FROM food_orders
SELECT restaurant_name,
addr,
CASE
WHEN addr LIKE '경기도%' THEN '경기도'
WHEN addr LIKE '%특별시%' OR addr LIKE '%광역시%' THEN SUBSTRING(addr,1,5)
ELSE SUBSTRING(addr,1,2)
END AS "변경된 주소"
FROM food_orders
a. 어떤 테이블에서 데이터를 뽑을 것인가 → from customers
b. 어떤 컬럼을 이용할 것인가 → name, age, gender
c. 어떤 조건을 지정해야 하는가 → 10 ≤ age < 30 → WHERE age BETWEEN 10 AND 29
d. 어떤 함수(수식) 이용해야 하는가 → CASE
e. 그룹 나누기 → 10대 여성, 10대 남성, 20대 여성, 20대 남성
SELECT name,
age,
gender,
CASE
WHEN (age BETWEEN 10 AND 19) AND gender='female' THEN "10대 여성"
WHEN (age BETWEEN 10 AND 19) AND gender='male' THEN "10대 남성"
WHEN (age BETWEEN 20 AND 29) AND gender='female' THEN "20대 여성"
WHEN (age BETWEEN 20 AND 29) AND gender='male' THEN "20대 남성"
END "그룹"
FROM customers
WHERE age BETWEEN 10 AND 29;
SELECT restaurant_name,
price/quantity "단가",
cuisine_type,
order_id,
CASE
WHEN (price/quantity < 5000) AND cuisine_type='Korean' THEN '한식1'
WHEN (price/quantity BETWEEN 5000 AND 15000) AND cuisine_type='Korean' THEN '한식2'
WHEN (price/quantity > 15000) AND cuisine_type='Korean' THEN '한식3'
WHEN (price/quantity < 5000) AND cuisine_type IN('Japanese', 'Chinese', 'Thai', 'Vietnamese', 'Indian') THEN '아시아식1'
WHEN (price/quantity BETWEEN 5000 AND 15000) AND cuisine_type IN('Japanese', 'Chinese', 'Thai', 'Vietnamese', 'Indian') THEN '아시아식2'
WHEN (price/quantity > 15000) AND cuisine_type IN('Japanese', 'Chinese', 'Thai', 'Vietnamese', 'Indian') THEN '아시아식3'
WHEN (price/quantity < 5000) AND cuisine_type NOT IN('Korean', 'Japanese', 'Chinese', 'Thai', 'Vietnamese', 'Indian') THEN '기타1'
WHEN (price/quantity BETWEEN 5000 AND 15000) AND cuisine_type NOT IN('Korean', 'Japanese', 'Chinese', 'Thai', 'Vietnamese', 'Indian') THEN '기타2'
WHEN (price/quantity > 15000) AND cuisine_type NOT IN('Korean', 'Japanese', 'Chinese', 'Thai', 'Vietnamese', 'Indian') THEN '기타3'
END
FROM food_orders;
SELECT order_id "주문 번호",
restaurant_name "식당 이름",
delivery_time "배달 시간",
price "가격",
addr "주소",
CASE
WHEN delivery_time > 30 THEN price*0.1*IF(addr LIKE '%서울특별시%', 1.1, 1)
WHEN delivery_time > 25 THEN price*0.05*IF(addr LIKE '%서울특별시%', 1.1, 1)
ELSE 0
END "배달수수료"
FROM food_orders
💡 30분 이상 25분 초과(delivery_time > 25 AND delivery_time <= 30)인데 25분 초과(delivery_time > 25)만 적어도 되는 이유: 첫 번째 WHEN에서 30분 초과라는 조건을 줘서 이미 30분 초과가 걸러진 다음 두 번째 WHEN으로 넘어가기 때문
하지만 조금 더 엄밀히 하고 싶다면 BETWEEN을 활용하는 것이 좋다. (delivery_time BETWEEN 26 AND 30)
SELECT order_id "주문 번호",
price "가격",
quantity "음식 수",
day_of_the_week "평일/주말",
IF(day_of_the_week='Weekday', 3000, 3500)*IF(quantity<=3, 1, 1.2) "배달할증료"
FROM food_orders
💡 다음의 조건으로 배달 시간이 늦었는지 판단하는 값을 만들어 주세요.
SELECT order_id,
restaurant_name,
day_of_the_week,
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