목차
Query
Query문 : 데이터베이스에 명령을 내리는 것
SELECT
SELECT 쿼리문 : 데이터베이스에서 데이터를 선택해서 가져옴, 1) 어떤 테이블에서 2) 어떤 필드의 데이터를 가져올지로 구성
테이블 : 데이터가 담긴 엑셀 시트와 동일
필드 : 각각의 열
select created_at, course_title, payment_method, email from orders;
show tables
일부 데이터만 가져오기 :
LIMIT
중복 데이터 제외하고 가져오기 :
DISTINCT
몇 개인지 숫자 세기 :
COUNT
별칭 :
ALIAS
WHERE
WHERE 절 : SELECT 쿼리문으로 가져올 데이터에 조건을 걸어줌
select * from orders
where payment_method = "kakaopay";
- 자주 사용하는 문법
- 같지 않음 :
!=
- 범위 :
BETWEEN ___ AND ___
- 포함 :
IN
- 패턴 :
LIKE
- 같지 않음 :
GROUP BY
GROUP BY : 동일한 범주를 갖는 데이터를 하나로 묶어 범주별 통계를 냄
- 개수 :
COUNT
- 최솟값 :
MIN
- 최댓값 :
MAX
- 평균 :
AVG
- 합계 :
SUM
select name, count(*) from users
group by name;
ORDER BY
ORDER BY : 데이터를 정렬함
select name, count(*) from users
group by name
order by count(*);
- 오름차순(default) :
ASC
- 내림차순 :
DESC
JOIN
JOIN : 두 테이블의 공통된 정보를 기준으로 테이블을 연결해서 한 테이블처럼 봄
LEFT JOIN
- 꽉찬 데이터 : 해당 데이터의 필드값이 테이블에 존재해서 연결한 경우
- 비어있는 데이터 : 해당 데이터의 필드값이 테이블에 존재하지 않는 경우
INNER JOIN
select * from users u inner join point_users p on u.user_id = p.user_id;
쿼리 실행 순서 : from → join → where → group by → select → order by
UNION
UNION : SELECT
두 번 하지 않고 한 번에 모아서 보고싶은 경우
(
select '7월' as month, c.title, c2.week, count(*) as cnt from checkins c2
inner join courses c on c2.course_id = c.course_id
inner join orders o on o.user_id = c2.user_id
where o.created_at < '2020-08-01'
group by c2.course_id, c2.week
order by c2.course_id, c2.week
)
union all
(
select '8월' as month, c.title, c2.week, count(*) as cnt from checkins c2
inner join courses c on c2.course_id = c.course_id
inner join orders o on o.user_id = c2.user_id
where o.created_at >= '2020-08-01'
group by c2.course_id, c2.week
order by c2.course_id, c2.week
)
- 내부 정렬이 되지 않기 때문에 서브쿼리 사용
SUBQUERY
SUBQUERY : 쿼리 안의 쿼리로 원하는 데이터를 더 편하고 간단하게 얻음
WHERE
에 들어가는 SUBQUERY : 서브쿼리의 결과를 조건에 활용하는 방식select * from users u where u.user_id in (select o.user_id from orders o where o.payment_method = 'kakaopay');
SELECT
에 들어가는 SUBQUERY : 기존 테이블에 함께 보고싶은 통계 데이터를 쉽게 붙이는 방식select c.checkin_id, c.user_id, c.likes, (select avg(likes) from checkins c2 where c2.user_id = c.user_id) as avg_like_user from checkins c;
FROM
에 들어가는 SUBQUERY : 만들어둔SELECT
와 이미 있는 테이블을JOIN
하고 싶을 때 사용하는 방식select pu.user_id, a.avg_like, pu.point from point_users pu inner join ( select user_id, round(avg(likes),1) as avg_like from checkins group by user_id ) a on pu.user_id = a.user_id
WITH : 계속해서 서브쿼리가 붙을 때 보기 좋게 만들어 줌
- BEFORE
select c.title, a.cnt_checkins, b.cnt_total, (a.cnt_checkins/b.cnt_total) as ratio from ( select course_id, count(distinct(user_id)) as cnt_checkins from checkins group by course_id ) a inner join ( select course_id, count(*) as cnt_total from orders group by course_id ) b on a.course_id = b.course_id inner join courses c on a.course_id = c.course_id
- AFTER
with table1 as ( select course_id, count(distinct(user_id)) as cnt_checkins from checkins group by course_id ), table2 as ( select course_id, count(*) as cnt_total from orders group by course_id ) select c.title, a.cnt_checkins, b.cnt_total, (a.cnt_checkins/b.cnt_total) as ratio from table1 a inner join table2 b on a.course_id = b.course_id inner join courses c on a.course_id = c.course_id
실전에서 유용한 SQL 문법
문자열 데이터
SUBSTRING_INDEX : 문자열 쪼개기SUBSTRING_INDEX(email, '@', 1)
→ 이메일에서 아이디만 가져옴SUBSTRING_INDEX(email, '@', -1)
→ 이메일에서 도메인만 가져옴
SUBSTRING : 문자열 일부 가져오기SUBSTRING(문자열, 출력을 하고싶은 첫 글자의 위치, 몇 개의 글자를 출력하고 싶은지)
CASE
CASE : 경우에 따라 원하는 값을 출력함
select pu.point_user_id, pu.point,
(case when pu.point > 10000 then '잘 하고 있어요!'
else '조금 더 달려주세요!' END) as '구분'
from point_users pu;