스파르타코딩클럽]엑셀보다 쉬운SQL 강의, 용어 정리

Kunwoong Song·2023년 3월 31일
0

Select, Where

_SELECT * from orders o
WHERE payment method ='kakaopay'
-> 코드의 의미는

  • ‘Select’ ALL from ‘Orders’
  • payment_method에서 kakaopay를 쓴 데이터

#작은 따옴표 꼭 써야한다.

  • kakaopay는 문자열 string이고
  • Orders는 테이블을 지칭하고
  • payment_method는 필드명을 지칭 하는 것이다.

SQL문은 점점 길어지면 햇갈림. 눈이 보게 좋게 정리하는게 중요.

예2) point_users 테이블에서 포인트가 5000점 이상인 데이터만 가져와줘!

SELECT * frompoint_users
WHERE point >=5000

예3) orders 테이블에서 주문한 강의가 앱개발 종합반이면서, 결제수단이 카드인 데이터만 가져와줘!

SELECT * from orders o
WHERE course_title ='앱개발 종합반' AND payment_method ='CARD'

#’또는’을 이용하게 된다면 OR를 적으면 된다.

Where절과 같이 쓰이는 분법

“!=” 같지 않음을 의미

#웹개발종합반을 빼고 데이터를 보고싶다면…

SELECT * from orders o
WHERE course_title !='웹개발 종합반'

“between” 범위조건

#7/13~7/14일 데이터를 보고싶다

SELECT * from orders o
WHERE created_at BETWEEN '2020-07-13' and '2020-07-15'

“in( )”포함

#1, 3주차 사람들의 오늘의 다짐 데이터만 보고싶다.

SELECT * from checkins c
WHERE week in(1,3)

  • 2개만 들어가지 않고 더 많이 들어갈 수 있다.

“like” 패턴으로 찾기

#다음 이메일만 쓰는 사람들의 유저를 보고싶다.

SELECT * FROM users
WHERE email LIKE '%daum.net'

  • ‘%’를 써서 ‘daum.net’으로 끝나는 이메일을 찾으라고 요청하는 것이다.

예.) a로 끝나고, t로 끝나는 이메일을 요청:

SELECT * FROM users
WHERE email LIKE 'a%t'

‘limit’ 일부 데이터만 가져오기

SELECT * FROM orders
WHERE payment_method ='kakaopay'
LIMIT 5

#위와 같은 코드는 결과를 5개로만 한정되어 나오게 한다.

  • 데이터가 많으면 처리하기가 오래걸릴 수도 있다. limit를 걸면 더 빠른결과.

‘distinct’ 중복되는 값 제거

SELECT payment_method from orders

위와 같은 코드를 쓰면 중복되는 값이 전부 다 나온다.

SELECT DISTINCT payment_method from orders o

→ 중복되는 값 제거함.

‘count’

SELECT count(*)FROM orders

데이터의 개수를 알린다.

SELECT count(*)FROM orders
WHERE payment_method ='kakaopay'

→ 카카오페이로 결제한 사람들의 데이터의 개수를 추출한다.

dinstinct와 count를 같이 써보기

SELECT count(DISTINCT(name)) from users u

→ the amount of unique names in a set data.

group by

SELECT name, count(*) from users
group by name

위의 코드는 이름과 그 이름의 개수를 통계 해준다.

  • ‘group by name을 통해 users를 각각의 name으로 묶었다.
  • name과 count(*)를 통해 각 이름마다의 개수를 세게 되었다.

#외우기 좋은 순서:

select * from users → group by name.

  • 이름마다의 개수가 목적이니 select안의 코드를 바꾼다.

select name, count(*) from users … → …

where문으로 검증하기

**select** **week**, **count**(*) **from** checkins
**group** **by** **week
select** * **from** checkins c
**where** **week**=1

#주차의 결과가 전부 나온다.

Q. 주차별로 like개수의 최소값

min( ) and max( )

SELECT week, min(likes) from checkins
group by week

#group by를 쓰지 않으면 1주차의 결과만 나온다.

min( ) 괄호 안에 해당 값의 최솟값을 불러온다.

→ 최댓값을 찾는다면 max( )로 바꾸면 된다.

Q.좋아요의 평균값을 구하라

avg( )

SELECT week, avg(likes) from checkins c 
group by week

round( )

SELECT week, round(avg(likes),2) from checkins c 
group by week

#’2’는 소수점 둘째 자리 까지 반올림을 한 다는 의미. 비워둔다면 1의 자리로 반올림 한다.

동일한 범주에 합계 구하기

sum( )
SELECT week, sum(likes) from checkins
group by week

order by

  • 결과를 정렬하기이다.
SELECT name, count(*) from users 
group by name

→ 이와 같이 나온 결과를 정렬하고자 한다.

SELECT name, count(*) from users 
group by name
order by count(*) desc

→ ‘desc’ (descending)를 위 코드와 같이 적게 된다면 역순으로 결과가 나온다.

#참고: ‘asc’가 오름차순을 의미. 쓸 필요 없을 것. 이미 기본이 오름차순.

별칭, alias 기능
:

SELECT payment_method, count(*) as cnt from orders o
where o.course_title = '앱개발 종합반'
group by payment_method

→ count(*)이 보기 안 좋아서 as cnt로 대체를 할 수도 있다.

join 종류: Left Join, Inner Join (Outer Join)

left join (or)

select * from users u 
left join point_users pu on u.user_id = pu.user_id

→ 위의 코드로 users테이블에 point_users의 정보를 넣는다.

  • 일부 NULL이 나오는데, 포인트가 없는 사람들이다.
  • 일종의 합집합이 나오는 것이다.

하지만, 만약 inner join을 쓰게 된다면: (and)

select * from users u 
inner join point_users pu on u.user_id = pu.user_id
  • NULL이 안나온다. point가 있는 사람들만 나와서, 두개의 교집합이 나온다는 것으로 생각하면 된다.

결과물 합치기, Union

두개의 표를 같다 붙이는 기능이 유니언.

select '7월' as month, c1.title, c2.week, count(*) as cnt from courses c1
inner join checkins c2 on c1.course_id = c2.course_id
inner join orders o on c2.user_id = o.user_id
where o.created_at < '2020-08-01'
group by c1.title, c2.week
order by c1.title, c2.week

select '8월' as month, c1.title, c2.week, count(*) as cnt from courses c1
inner join checkins c2 on c1.course_id = c2.course_id
inner join orders o on c2.user_id = o.user_id
where o.created_at >= '2020-08-01'
group by c1.title, c2.week
order by c1.title, c2.week

위와 같은 코드는 두개의 별도의 표가 만들어진다.

#union all 을 활용해서 하면 된다.

(
	select '7월' as month, c1.title, c2.week, count(*) as cnt from courses c1
	inner join checkins c2 on c1.course_id = c2.course_id
	inner join orders o on c2.user_id = o.user_id
	where o.created_at < '2020-08-01'
	group by c1.title, c2.week
	order by c1.title, c2.week
)
union all
(
	select '8월' as month, c1.title, c2.week, count(*) as cnt from courses c1
	inner join checkins c2 on c1.course_id = c2.course_id
	inner join orders o on c2.user_id = o.user_id
	where o.created_at >= '2020-08-01'
	group by c1.title, c2.week
	order by c1.title, c2.week
)

→ 하지만, 이 내에서 order by 기능이 먹히지 않는다.

subquery

select u.user_id , u.name , u.email  from users u
inner join orders o on u.user_id =o.user_id 
where o.payment_method = "kakaopay"

위와 같은 코드를 sub-query로 해결 할 수도 있다.

#sub-query를 이용한다면:

SELECT * from users u 
where user_id in (
	select user_id from orders o 
	where payment_method = 'kakaopay'
)

→ 실행 순서:

  • 괄호 안에 있는 쿼리를 먼저 결과를 만든 다음에 밖에 있는 뭐리를 해결한다.

Where에 들어가는 sub-query

where (필드명) in (sub-query)

user_id가 방금 뽑은 데이터 안에 있는지 확인

Select에 들어가는 sub-query

select 필드명, 필드명, (sub-query) from …

#checkins table에서 user id별, 평균 라이크 수를 본다.

SELECT checkin_id, 
		user_id, 
		likes,
		(
			SELECT avg(likes) from checkins
			where user_id = c.user_id 
		) as avg_likes
	from checkins c
  • 괄호 안에 있는 쿼리를 실행 하면서 매 user_id마다 라이크 수 의 평균을 만드는 중이다.

From에 들어가는 sub-query (가장 많이 사용되는 유형이기도 한다.)

우선 유저별 평균 좋아요:

SELECT pu.user_id , pu.`point`, a.avg_likes from point_users pu 
inner join (
	SELECT user_id, round(avg(likes),1) as avg_likes from checkins
	group by user_id ) a 
		on pu.user_id = a.user_id

마치 이미 있던 테이블 처럼 쓰는 것이다.

profile
삐삐 쀼루 삐뽀

0개의 댓글