4주차 동안 작성한 코드
SELECT u.user_id, u.name, u.email from orders o
inner join users u
on u.user_id = o.user_id
where o.payment_method = 'kakaopay'
SELECT u.user_id, u.name, u.email FROM users u
where user_id in (
select user_id from orders
WHERE payment_method = 'kakaopay'
)
select user_id from orders o
WHERE payment_method = 'kakaopay'
SELECT c.checkin_id , c.user_id , c.likes FROM checkins c
SELECT c.checkin_id,
c.user_id,
likes,
(
SELECT AVG(likes) FROM checkins c2
WHERE user_id = c.user_id
)
as AVG_Likes_user
FROM checkins c
SELECT AVG(likes) FROM checkins c
WHERE user_id = '4b8a10e6'
SELECT user_id , round(AVG(likes),1) as avg_likes FROM checkins c
GROUP BY user_id
SELECT user_id , point FROM point_users pu
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 c
group by user_id
) a on pu.user_id = a.user_id
SELECT * From point_users pu
WHERE `point` > 5000
SELECT round(avg(point),1) from point_users pu
SELECT * FROM point_users pu
inner join (
select round(avg(point)) as tot_avg_point from point_users pu2
) a on a.tot_avg_point <= pu.point
SELECT * FROM point_users pu
WHERE point > (
select avg(point) from point_users pu2
)
SELECT ROUND(AVG(pu.point)) FROM point_users pu
inner join users u
on u.user_id =pu.user_id
where u.name = "이**"
SELECT * FROM point_users pu
WHERE pu.user_id in (
select user_id from users u
where name = "이**"
)
SELECT * FROM point_users pu
where pu.`point` > (
select avg(point) from point_users pu2
inner join users u
on u.user_id = pu2.user_id
where u.name = "이**"
)
SELECT * FROM point_users pu
WHERE pu.`point` > (
select avg(point) from point_users pu2
where pu2.user_id in (
select user_id from users u
WHERE name = "이**"
)
)
SELECT * FROM checkins c
inner join (
select * , round(avg(likes),1) as cource_avg from checkins c2
group by c2.course_id
) a
on c.course_id = a.course_id
SELECT c.checkin_id ,
c.course_id ,
c.user_id ,
c.likes ,
a.cource_avg
FROM checkins c
inner join (
select * , round(avg(likes),1) as cource_avg from checkins c2
group by c2.course_id
) a
on c.course_id = a.course_id
SELECT c.checkin_id ,
c.course_id ,
c.user_id ,
c.likes ,
(
select round(avg(c2.likes),1) from checkins c2
WHERE c2.course_id = c.course_id
) as course_avg
FROM checkins c
SELECT * FROM courses c
SELECT c.checkin_id ,
c.course_id ,
c.user_id ,
c.likes ,
(
select round(avg(c2.likes),1) from checkins c2
where c.course_id = c2.course_id
),
a.title
FROM checkins c
inner join (
select * from courses c3
) a
on a.course_id = c.course_id
SELECT c.checkin_id ,
c.course_id ,
c.user_id ,
c.likes ,
(
select round(avg(c2.likes),1) from checkins c2
where c.course_id = c2.course_id
),
c3.title
FROM checkins c
inner join courses c3
on c3.course_id = c.course_id
SELECT course_id , count(DISTINCT(user_id)) as cnt_checkins FROM checkins c
group by course_id
SELECT course_id , COUNT(DISTINCT(user_id)) FROM orders o
GROUP BY course_id
SELECT a.course_id,a.cnt_checkins, b.cnt_tot FROM (
select c.course_id, count(distinct(user_id)) as cnt_checkins from checkins c
group by c.course_id
) a
inner join (
select o.course_id, count(distinct(user_id)) as cnt_tot from orders o
group by o.course_id
) b
on a.course_id = b.course_id
SELECT (
select title from courses c2
where c2.course_id = a.course_id
) as title,
a.course_id,
a.cnt_checkins,
b.cnt_total,
(a.cnt_checkins / b.cnt_total) as ratio
FROM
(
select c.course_id, count(distinct(user_id)) as cnt_checkins from checkins c
group by c.course_id
) a
INNER JOIN (
select o.course_id, count(*) as cnt_total from orders o
group by o.course_id
) b
ON a.course_id = b.course_id
ORDER BY title
SELECT c2.title,
a.course_id,
a.cnt_checkins,
b.cnt_total,
(a.cnt_checkins / b.cnt_total) as ratio
FROM
(
select c.course_id, count(distinct(user_id)) as cnt_checkins from checkins c
group by c.course_id
) a
INNER JOIN (
select o.course_id, count(*) as cnt_total from orders o
group by o.course_id
) b
ON a.course_id = b.course_id
INNER JOIN courses c2 on a.course_id = c2.course_id
ORDER BY title
with table1 as (
select c.course_id, count(distinct(user_id)) as cnt_checkins from checkins c
group by c.course_id
), table2 as (
select o.course_id, count(*) as cnt_total from orders o
group by o.course_id
)
SELECT c2.title,
a.course_id,
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 c2 on a.course_id = c2.course_id
ORDER BY title
SELECT user_id ,
email ,
SUBSTRING_INDEX(email,'@', 1) as email_id ,
SUBSTRING_INDEX(email,'@',-1) as email_domain
FROM users u
SELECT order_no , created_at , SUBSTRING(created_at,1,10) as date FROM orders o
SELECT order_no , created_at , SUBSTRING(created_at,1,10) as date FROM orders o
group by date
SELECT order_no , created_at , SUBSTRING(created_at,1,10) as date, COUNT(*) FROM orders o
group by date
SELECT created_at, SUBSTRING(created_at,12,8) FROM orders o
SELECT pu.user_id , pu.point ,
(case when pu.point > 10000 then '잘 하고 있어요!'
else '조금만 더 화이팅!' end) as msg
FROM point_users pu
SELECT pu.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
SELECT a.lv, COUNT(*) FROM (
select pu.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 a.lv
with table1 as (
select pu.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
)
SELECT a.lv, COUNT(*) FROM table1 a
group by a.lv
SELECT pu.point_user_id ,
pu.`point` ,
(
case
when pu.`point` > (select SUM(pu2.`point`)/count(*) from point_users pu2) then '잘 하고 있아요!'
else '열심히 합시다!'
end
)as msg
FROM point_users pu
SELECT pu.point_user_id ,
pu.`point` ,
(
case
when pu.`point` > (select avg(point) from point_users pu2) then '잘 하고 있아요!'
else '열심히 합시다!'
end
)as msg
FROM point_users pu
SELECT SUBSTRING_INDEX(email,'@',-1) as domain,
COUNT(*) as cnt_domain
FROM users u
GROUP BY domain
SELECT domain, count(*) as cnt FROM (
SELECT SUBSTRING_INDEX(email,'@',-1) as domain
FROM users u
) a
group by domain
SELECT * FROM checkins c
WHERE comment like '%화이팅%'
SELECT * FROM (
select * from checkins c
where comment like '%화이팅%'
) a
SELECT enrolled_id , count(*) as total_cnt FROM enrolleds_detail ed
GROUP BY enrolled_id
SELECT enrolled_id , SUM(done) From enrolleds_detail ed
GROUP BY enrolled_id
SELECT enrolled_id , SUM(done) From enrolleds_detail ed
WHERE ed.done = 1
GROUP BY enrolled_id
SELECT a.enrolled_id , b.done_cnt , a.total_cnt FROM (
SELECT enrolled_id , count(*) as total_cnt FROM enrolleds_detail ed
GROUP BY enrolled_id
) a
INNER JOIN (
SELECT enrolled_id , SUM(done) as done_cnt From enrolleds_detail ed
WHERE ed.done = 1
GROUP BY enrolled_id
) b
ON a.enrolled_id = b.enrolled_id
ORDER BY a.enrolled_id
with table1 as (
select enrolled_id , count(*) as total_cnt from enrolleds_detail ed
group by enrolled_id
), table2 as (
select ed2.enrolled_id , sum(ed2.done) as done_cnt from enrolleds_detail ed2
where ed2.done = 1
group by ed2.enrolled_id
)
SELECT a.enrolled_id, b.done_cnt, a.total_cnt FROM table1 a
INNER JOIN table2 b
ON a.enrolled_id = b.enrolled_id
with table1 as (
select enrolled_id , count(*) as total_cnt from enrolleds_detail ed
group by enrolled_id
), table2 as (
select ed2.enrolled_id , sum(ed2.done) as done_cnt from enrolleds_detail ed2
where ed2.done = 1
group by ed2.enrolled_id
)
SELECT a.enrolled_id,
b.done_cnt, a.total_cnt ,
ROUND((b.done_cnt/a.total_cnt),2) as ratio
FROM table1 a
INNER JOIN table2 b
ON a.enrolled_id = b.enrolled_id
subquery는 쿼리 안에 쿼리를 집어 넣는 것이다. 작은 쿼리(subquery)에서 나온 결과를 쿼리에서 사용하는 것으로 쿼리가 더욱 간단해 진다.
서브 쿼리는 ()안에 작성해주어야 한다.
예)
SELECT a.TYPE FROM (
SELECT * FROM POKEMON
WHERE ANIMAL = 'RAT'
) a
이러면 포켓몬 테이블에서 동물 컬럼 값이 'RAT'인 데이터만을 가져와 a라 이름 붙이고 그 a에서 TYPE 데이터를 가져오라는 요청이 된다.
with을 사용하면 서브쿼리를 밖으로 빼내어 쿼리문을 더 보기 좋게 만들 수 있다.
예)
with table1 as (
SELECT * FROM POKEMON
WHERE ANIMAL = 'RAT'
)
SELECT a.TYPE FROM table1 a
이때 주의할 점은 with ~ a까지 전체 코드를 함께 선택한 다음에 실행시키지 않으면 with이 실행 안 된다는 것이다.
테이블을 복수 선언하고 싶을 때는 with을 여러번 쓰는 것이 아닌 ,로 테이블을 연달아 선언해야 한다.
예)
with table1 as (
SELECT * FROM POKEMON
WHERE ANIMAL = 'RAT'
), table2 as (
SELECT * FROM POKEMON
WHERE ATK > 25
)
if else 문과 비슷하다. case와 end 사이에 when으로 조건을 걸고 조건을 충족시킬 경우 그 값은 then 이후의 것이 된다. 모든 when을 충족시키지 못할 경우 else 다음 값을 가지게 된다.
예)
SELECT USER_ID,
(
case
when adven.level >250 then '충분한 레벨'
else '아직 모자른 편'
end
) as able_next
FROM MAPLESTROY_ADVENTURER adven
메이플스토리 모험가 테이블에서 유저 아이디와 유저 레벨에 따른 다음 스테이지 진입 가능 여부를 출력하는 코드이다.
여러 사람들과 함께 데이터를 꺼내 쓰기 쉽게 담아두는 통.
원하는 대로 저장하고 사용하기 위해 통상적으로 모든 데이터베이스는 CRUD에 해당하는 기능을 지원한다.
C(Create): 데이터 생성하는 것이다.
R(Read): 저장된 데이터 읽어오기, 즉 데이터 꺼내오는 것이다.
U(Update): 저장된 데이터를 변경, 즉 데이터 덮어쓰기는 것이다.
D(Delete): 저장된 데이터를 삭제하는 것이다.
Structured Query Language의 약자로 데이터베이스에 요청(Query)을 보내서 원하는 데이터를 가져오는 작업을 도와주는 언어라는 의미이다.
CRUD 중 R(Read)을 편하게 하기 위해서 필요하다. 데이터를 정리/분석하는 기능도 지원한다고 한다.
데이터 베이스(이하 DB)는 만들기 시작(C: Create)할 때부터 관리하는 것(U: Update)까지 전문적으로 설계를 해야 하기 때문에 실제 업무에서 주로 하는 것은 R이다.
실수로 D(Delete)를 하면 중대한 문제가 발생할 수 있으니 전문적으로 관리하는 인력이 따로 존재한다고 한다.
SHOW tables
존재하는 테이블의 목록을 호출한다.
SELECT 테이블 컬럼명(찾는 대상) FROM 테이블 이름
데이터 베이스에 보내는 질의문으로 테이블에서 지정한 데이터를 가져온다.
테이블로부터 지정한 컬럼명에 해당 하는 데이터를 가져온다.
FROM을 데이터를 가져올 테이블를 지정, SELECT는 테이블에서 가져올 데이터를 지정한다.
Where 조건
SELECT문을 작성한 다음에 작성하며, select로 가져올 데이터에 조건을 부여한다.
예시코드
SELECT * FROM POKEMON
WHERE TYPE='electronic'
포켓몬 테이블에서 타입이 전기인 데이터만을 가져오라는 요청이 된다.
참고로 AND나 OR을 사용해 여러 개를 함께 지정하는 것이 가능하다.
같지 않음(!=) 조건 걸기
지정된 조건과 일치하지 않는 데이터를 가져오도록 요청한다.
SELECT * FROM POKEMON
WHERE TYPE !='electronic'
포켓몬 테이블에서 타입이 전기가 아닌 데이터만을 가져오라는 요청이 된다.
범위 조건(between) 걸기
가져올 데이터의 범위를 지정한다.
SELECT * FROM POKEMON
WHERE ATK BETWEEN 100 AND 200
이렇게 하면 포켓몬 테이블에서 공격력이 100에서 200 사이인 데이터를 가져오라는 요청이 된다.
포함 조건(in (,,,)) 걸기
가져올 데이터에 해당 조건이 포함되도록 요청한다.
SELECT * FROM POKEMON
WHERE TYPE IN ('electronic','fairy','dragon')
이렇게 하면 포켓몬 테이블에서 타입이 전기, 페어리 혹은 드래곤인 데이터들을 가져오라는 요청이 된다.
패턴(문자열 규칙) 조건(like '%') 걸기
특정 문자를 포함한 문자열을 가지고 있을 것을 조건으로 건다.
SELECT * FROM POKEMON
WHERE name LIKE '%츄'
이렇게 하면 이름이 츄로 끝나는 모든 데이터를 가져오라는 요청이 된다.
일부 데이터만 가져오기(Limit)
가져올 데이터가 방대할 때 그 중 일부만 가져오기 위해 사용한다.
SELECT * FROM POKEMON
WHERE TYPE IN ('electronic','fairy','dragon')
LIMIT 10
이렇게 하면 포켓몬 테이블에서 타입이 전기, 페어리 혹은 드래곤인 데이터들 중 10개만을 가져오라는 요청이 된다.
중복 데이터는 제외하고 가져오기(Distinct)
가져올 데이터에서 중복을 제거하도록 요청한다.
SELECT DISTINCT(TYPE) FROM POKEMON
이렇게 하면 포켓몬 테이블에서 TYPE에 해당하는 데이터를 중복을 제외하고 가져오도록 요청한다.
몇 개인지 숫자 세기(Count)
데이터의 갯수를 세도록 요청한다,
SELECT COUNT(DISTINCT(TYPE)) FROM POKEMON
이렇게 하면 포켓몬 테이블에서 TYPE에 해당하는 데이터들의 중복을 제외한 갯수를 가져오도록 요청한다.
동일한 범주를 갖는 데이터를 하나로 묶어서, 범주별 통계를 내주는 것
select type,count(*) from pokemon
group by type
위 코드를 실행시키면 pokemon으로 부터 데이터를 가져와 type으로 묶은 뒤 type과 그 갯수를 출력해준다.
데이터를 오름차순, 내림차순으로 정렬해주는 것
desc은 내림차순, ASC는 오름차순이며 기본적으로 오름차순이다.
select type,count(*) from pokemon
group by type
order by count(*) desc
위 코드를 실행시키면 GROUP BY 예시코드의 결과를 내림차순으로 정렬하여 출력해준다.
쿼리가 길어지면서 생기는 혼동을 줄이기 위해 테이블명이나 데이터 필드명에 약어(같은 것)을 부여하는 것
as를 붙여서 필드명에 별칭을 추가할 수 있다. from에서 지정하는 데이블명에는 as가 생략되어도 문제가 없는 것 같다.
SELECT payment_method ,count(*) as cnt from orders o
WHERE o.course_title = '앱개발 종합반' and email like '%naver.com'
group by payment_method
위 코드의 count() as cnt는 출력될 count()에 cnt라는 별칭을 붙여 cnt로 출력되게 변경해준다.
orders o는 orders 테이블을 o라는 단어로 접근할 수 있게 해준다.
두 테이블의 공통된 정보를 기준으로 테이블을 연결해서 한 테이블처럼 보는 것
inner (교집합), left(처음 나오는 테이블에 합치는 방식), outer(거의 안씀)의 3가지 방식이 존재한다.
inner로 사용할 경우 일치하는 데이터가 있는 것만 합쳐서 가져오고, left일 경우에는 일치하는 것이 없을 경우 없는 자동으로 데이터를 NULL로 채워서 가져온다,.
SELECT * FROM checkins c
inner join users u
on c.user_id = u.user_id
select u.name, COUNT(*) as cnt from users u
left join point_users pu
on u.user_id = pu.user_id
WHERE pu.point_user_id is not NULL
GROUP by u.name
데이터가 없는 비어있음을 의미한다.
IS NULL - NULL인지 확인
IS NOT NULL - NULL이 아닌지 확인
COUNT는 NULL을 세지 않는다.
select u.name, COUNT(*) as cnt from users u
left join point_users pu
on u.user_id = pu.user_id
WHERE pu.point_user_id is not NULL
GROUP by u.name
데이터 명과 종류가 모두 동일할 때 사용할 수 있다.
서로 다른 테이블을 합쳐서 보여준다.
(
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
)
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
)
subquery는 쿼리 안에 쿼리를 집어 넣는 것이다. 작은 쿼리(subquery)에서 나온 결과를 쿼리에서 사용하는 것으로 쿼리가 더욱 간단해 진다.
서브 쿼리는 ()안에 작성해주어야 한다.
select, from, where에서 유용하게 사용되는 편
예)
SELECT a.TYPE FROM (
SELECT * FROM POKEMON
WHERE ANIMAL = 'RAT'
) a
이러면 포켓몬 테이블에서 동물 컬럼 값이 'RAT'인 데이터만을 가져와 a라 이름 붙이고 그 a에서 TYPE 데이터를 가져오라는 요청이 된다.
with을 사용하면 서브쿼리를 밖으로 빼내어 쿼리문을 더 보기 좋게 만들 수 있다.
예)
with table1 as (
SELECT * FROM POKEMON
WHERE ANIMAL = 'RAT'
)
SELECT a.TYPE FROM table1 a
이때 주의할 점은 with ~ a까지 전체 코드를 함께 선택한 다음에 실행시키지 않으면 with이 실행 안 된다는 것이다.
테이블을 복수 선언하고 싶을 때는 with을 여러번 쓰는 것이 아닌 ,로 테이블을 연달아 선언해야 한다.
예)
with table1 as (
SELECT * FROM POKEMON
WHERE ANIMAL = 'RAT'
), table2 as (
SELECT * FROM POKEMON
WHERE ATK > 25
)
if else 문과 비슷하다. case와 end 사이에 when으로 조건을 걸고 조건을 충족시킬 경우 그 값은 then 이후의 것이 된다. 모든 when을 충족시키지 못할 경우 else 다음 값을 가지게 된다.
예)
SELECT USER_ID,
(
case
when adven.level >250 then '충분한 레벨'
else '아직 모자른 편'
end
) as able_next
FROM MAPLESTROY_ADVENTURER adven
메이플스토리 모험가 테이블에서 유저 아이디와 유저 레벨에 따른 다음 스테이지 진입 가능 여부를 출력하는 코드이다.
from(데이터 가져오기) -> JOIN(데이터 합치기) -> where(특정 데이터만 가져오기) -> group by(데이터 묶기) -> select(해당하는 데이터 추출하기) -> order by(데이터 정렬하기)
subquery가 포함되어 있는 부분에서는 subquery를 진행 후 해당 부분을 진행한다,