스파르타 코딩클럽 - SQL 4주차

박민영·2023년 4월 1일
0

엑셀보다 쉬운 SQL

목록 보기
4/4
post-thumbnail

<1주차 문법>

Query

데이터베이스에 명령을 내리는 것

show tables

데이터베이스의 테이블 보기

select

데이터를 선택해서 가져오겠다

A 테이블의 데이터 가져와보기

select * from A

A 테이블의 특정필드만 가져와보기

select a, b, c, d from A

where

가져올 데이터에 조건을 걸어주는 것

ex) orders 테이블에서 payment_method가 kakaopay인 것만 가져오기

select * from orders
where payment_method = "kakaopay"

"문자열"

필드명이나 테이블명이 아닌 문자열로 인식시킬 경우 "" 넣기

여러 조건을 걸 때는

select * from A
where a = "에이" and b = "비"

ex) '20000점 보다 많은 점수를 가진 유저만 뽑아보기'

select * from point_users
where point > 20000

성씨를 가져올 때

select * from users
where name = "황**"

같지않음

where a != '에이'

범위

where a between '0000-00-00' and '0000-00-00'

포함

where week in (1,3)
= 1, 3주차만 포함시켜달라

패턴

where email like '%naver.com'
= 앞의 아이디 상관없이 도메인이 naver.com인 것만 불러달라

where email like '%'사용법

'a%' : a로 시작하는 모든 데이터
'%a' : a로 끝나는 모든 데이터
'%a%' : a를 포함하는 모든 데이터
'a%b' : a로 시작하고 b로 끝나는 모든 데이터

limit 숫자

너무 많은 데이터 중 일부 데이터만 물러오기

distinct

중복 데이터 제외하고 가져오기
select distinct(a) from A

count

숫자 세보기
select count(*) from A

round

소수점 자리가 나오는 숫자일 경우, round(count(), 1) 형태로 씀.
1은 소수 첫째 자리까지 나온다는 의미

비율

a/b

<2주차 문법>

group by

동일한 범주를 갖는 데이터를 하나로 묶어 범주별 통계를 내주는 것
'~별'이라고 나오면 그룹으로 묶어라

a별 개수 구하기

select a, count() from A
group by a
반드시 select 뒤에 그룹으로 묶은 필드명과 count(
) 적기

a별 b필드의 최솟값 구하기

select a, min(b) from A
group by a

a별 b필드의 최댓값 구하기

select a, max(b) from A
group by a

a별 b필드의 평균값 구하기

select a, avg(b) from A
group by a

a별 b필드의 합계 구하기

select a, sum(b) from A
group by a

order by

데이터 정렬하기
맨 마지막에 적기
숫자, 문자열, 시간을 기준으로 정렬할 수 있음.
기본은 오름차순, 뒤에 desc를 넣으면 내림차순

ex) 결과의 개수 내림차순으로 정렬해보기

select name, count() from users
group by name
order by count(
) desc

Alias

별칭 기능
테이블명 뒤에 as alias를 붙이거나 출력될 필드에 별칭을 붙일 수도 있음

<3주차 문법>

join

두 테이블의 공통된 정보를 기준으로 테이블을 연결해서 한 테이블처럼 보는 것.

형태

select * from A
left(inner) join B
on A.c = B.c
(c는 공통된 필드)

Left join

A테이블에 B테이블을 붙이라는 뜻이지만 두 테이블 데이터에 따라 채워진 필드도, 비워진 필드도 있을 수 있다.
그런 경우, 'null'이라고 표시됨

is null, is not null

데이터가 없는 정보를 얻을 경우 : is null
데이터가 있는 정보를 얻을 경우 : is not null
null은 count에서 세지 않음.

Inner join

A,B 테이블 둘 다 가지고 있는 데이터만 출력

ex) 과목별 오늘의 다짐 갯수 세어보기

select co.title, count(co.title) as checkin_count from checkins ci
inner join courses co
on ci.course_id = co.course_id
group by co.title

순서

select ~~ from ~~
inner join ~~
on ~~ = ~~
where ~~
group by ~~
order by ~~

Union

select를 한번에 모아서 보고 싶을 경우
(
select문 1
)
union all
(
select문 2
)
단, union을 사용할 경우 내부에 있는 order by가 먹히지 않음.
대신 사용하는 것이 SubQuery.

<4주차 문법>

SubQuery

쿼리 안의 쿼리

where에 들어가는 subquery

subquery의 결과를 조건으로 활용하는 방식
where 필드명 in subquery

ex) 카카오페이로 결제한 주문건 유저들만, 유저 테이블에서 출력해주고 싶을 때

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

select에 들어가는 subquery

기존 테이블과 함께 보고 싶은 통계 데이터를 붙이기
select 필드명, 필드명, (subquery) from ..

ex) '오늘의 다짐' 좋아요의 수가, 본인이 평소에 받았던 좋아요 수에 비해 얼마나 높고 낮은가

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 필드명 from (subquery)

ex) 포인트와 like의 상관정도

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절

더 깔끔하게 쿼리문 정리할 때
with tables1 as (
select문 1
), table2 as(
select문 2
)

ex)

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

SUBSTRING_INDEX

문자열 쪼개기

ex) 이메일에서 아이디만 가져와보기

select user_id, email, SUBSTRING_INDEX(email, '@', 1) from users
= @ 앞의 아이디만 나옴.
1 대신 -1을 넣을 경우 @ 뒤의 도메인만 나옴

SUBSTRING

문자열 일부만 출력하기

ex) orders 테이블에서 날짜까지 출력하게 해보기

select order_no, created_at, substring(created_at,1,10) as date from orders

case

경우에 따라 언하는 값을 새 필드에 출력하기(if문과 비슷)

ex) 포인트 보유액에 따라 다르게 표시해주기

select level, count(*) as cnt from (
select pu.point_user_id, pu.point,
case
when pu.point > 10000 then '1만 이상'
when pu.point > 5000 then '5천 이상'
else '5천 미만'
END as lv
from point_users pu
) a
group by lv

profile
개발자로 취뽀하기!!

0개의 댓글