๐ฅ Subquery๋?
- ์ฟผ๋ฆฌ ์์ ์ฟผ๋ฆฌ
- ํ์ ์ฟผ๋ฆฌ์ ๊ฒฐ๊ณผ๋ฅผ ์์ ์ฟผ๋ฆฌ์์ ์ฌ์ฉํ๋ค.
- ์์ฃผ ์ฐ์ด๋ Subqueary ์ ํ: Where์ ๋ค์ด๊ฐ๋ Subquery, Select์ ๋ค์ด๊ฐ๋ Subquery, From์ ๋ค์ด๊ฐ๋ Subquery
- () ์์ subquery๊ฐ ๋ค์ด๊ฐ๋ค.
๐ฅ Where ์ ์ ๋ค์ด๊ฐ๋ Subquery
Subquery์ ๊ฒฐ๊ณผ๋ฅผ ์กฐ๊ฑด์ ํ์ฉํ๋ค.
where ํ๋๋ช
in (subquery)
์ฌ์ฉ ์์
- ์นด์นด์ค ํ์ด๋ก ๊ฒฐ์ ํ ์ฃผ๋ฌธ๊ฑด ์ ์ ๋ค๋ง ์ ์ ํ ์ด๋ธ์์ ์ถ์ถ
select * from users u
where u.user_id in (select o.user_id from orders o
where o.payment_method = 'kakaopay');
โป ์ฟผ๋ฆฌ ์คํ ์์: from → where์ ์ subquery → where → select
1. from users u : users์ ๋ฐ์ดํฐ๋ฅผ ๋ชจ๋ ๊ฐ์ ธ์จ๋ค.
2. (select o.user_id from orders o
where o.payment_method = 'kakakopay') : ์นด์นด์ค ํ์ด๋ก ๊ฒฐ์ ํ user_id ๋ช ๋จ์ ๋ฝ๋๋ค.
3. where u.user_id in () : subquery์ ๊ฒฐ๊ณผ์ ํด๋น๋๋ 'user_id์ ๋ช ๋จ' ์กฐ๊ฑด์ผ๋ก ํํฐ๋ง ํ๋ค.
4. select * : ์กฐ๊ฑด์ ๋ง๋ users ํ ์ด๋ธ์ ๋ชจ๋ ๋ฐ์ดํฐ ์ถ๋ ฅ
- ์ด์จ ์ฑ์ ๊ฐ์ง ์ ์ ๋ค์ ํ๊ท ํฌ์ธํธ๋ณด๋ค ๋ ๋ง์ ํฌ์ธํธ๋ฅผ ๊ฐ์ง๊ณ ์๋ ๋ฐ์ดํฐ ์ถ์ถ
select * from point_users pu
where pu.point > (
select round(avg(pu2.point)) from point_users pu2
where pu2.user_id in
(
select u.user_id from users u
where u.name = '์ด**'
)
)
subquery์์ subquery๊ฐ ๋ค์ด๊ฐ ์ ์๋ค.
select * from point_users pu
where pu.point >
(select avg(pu2.point) from point_users pu2
inner join users u
on pu2.user_id = u.user_id
where u.name = "์ด**");
subquery ํด์:
point ์ ๋ณด๋ point_usersํ ์ด๋ธ ์์ ์๊ณ , name ์ ๋ณด๋ users ํ ์ด๋ธ ์์ ์์ผ๋ฏ๋ก, ๋ ํ ์ด๋ธ์ ํฉ์น๋ค.
๊ทธ ํ ํฉ์น ํ ์ด๋ธ์์ ์ฑ์ด ์ด์จ์ธ ๋ฐ์ดํฐ๋ค๋ง ์ถ์ถํ๋๋ก ์กฐ๊ฑด์ ๊ฑธ๊ณ , ๊ทธ ๋ฐ์ดํฐ์ point ํ๊ท ์ ๊ตฌํ๋ค.
๐ฅ Select ์ ์ ๋ค์ด๊ฐ๋ Subquery
Select๋ ๊ฒฐ๊ณผ๋ฅผ ์ถ๋ ฅํด์ฃผ๋ ๋ถ๋ถ.
๊ฒฐ๊ณผ๋ฅผ ์ถ๋ ฅํ ๋, ๊ธฐ์กด ํ ์ด๋ธ์ ํจ๊ป ๋ณด๊ณ ์ถ์ ํต๊ณ ๋ฐ์ดํฐ๋ฅผ Subquery๋ฅผ ์ด์ฉํด ๋ถ์ธ๋ค.
select ํ๋๋ช
, ํ๋๋ช
, (subquery) from ...
select * from ๋ฌธ์์ ๋ฐ์ดํฐ๋ ํ์ค ํ์ค ์ถ๋ ฅํ๋ค. select ์์ Subquery๋ ๋งค ๋ฐ์ดํฐ ํ์ค๋ง๋ค ์คํ๋๋ค.
์ฌ์ฉ ์์
- '์ค๋์ ๋ค์ง'(chekins) ๋ฐ์ดํฐ๋ฅผ ๋ณด๊ณ ์ถ์๋ฐ, course_id๊ฐ ๋ฐ์๋ ์ข์์ ์ ํ๊ท ์ checkins ํ ์ด๋ธ course_id๋ง๋ค ๋ถ์ธ๋ค.
select
checkin_id,
course_id,
user_id,
likes,
(
select round(avg(c2.likes),1) from checkins c2
where c.course_id = c2.course_id
) as course_avg
from checkins c
1. select * from ๋ฌธ์์ ๋ฐ์ดํฐ๋ฅผ ํ์ค ํ์ค ์ถ๋ ฅํ๋ ๊ณผ์ ์์
2. select ์์ subquery๊ฐ ๋งค ๋ฐ์ดํฐ ํ์ค๋ง๋ค ์คํ๋๋ค.
3. ๊ทธ ๋ฐ์ดํฐ ํ ์ค์ course_id๋ฅผ ๊ฐ๋ ๋ฐ์ดํฐ์ ํ๊ท ์ข์์ ๊ฐ์ subquery์์ ๊ณ์ฐํด์
4. ํจ๊ป ์ถ๋ ฅํ๋ค.
๐ฅ From ์ ์ ๋ค์ด๊ฐ๋ Subquery
์ฌ๋ฌ table์์ selectํ๊ณ ์ถ์ ๋ from์ ์ subquery๋ฅผ ์ฌ์ฉํ๋ค.
1. selectํ๊ณ ์ถ์ ์ ๋ณด๊ฐ ๋ค์ด ์๋ ํ ์ด๋ธ๋ค์์, ๊ฐ์ select๋ฅผ ์ํํด ์๋ก์ด ํ ์ด๋ธ์ด ๋๋ค.
2. subquery๋ฅผ ์ด์ฉํด ์ํ๋ ์ ๋ณด๋ค์ด ์๋(select๊ฐ ์ํ๋) ํ ์ด๋ธ๋ค์ join ํ๋ค.
(๋์ค์ selectํ ๋๋ฅผ ์ํด ๋ณ์นญ์ ์ฌ์ฉํ๋ค.)
3. join๋ ๊ฐ ํ ์ด๋ธ์ ๋ณ์นญ์ ์ด์ฉํด ์ํ๋ ๋ฐ์ดํฐ๋ค์ selectํ๋ค.
์ฌ์ฉ ์์
์ถ์ถํ๊ณ ์ถ์ ๋ฐ์ดํฐ: course title, course๋ณ ์ ์ ์ ์ฒดํฌ์ธ ๊ฐ์, course๋ณ ์ธ์, ํผ์ผํธ
1. course_id๋ณ ์ ์ ์ ์ฒดํฌ์ธ ๊ฐ์๋ฅผ ๊ตฌํ๋ค.
select course_id, count(distinct(user_id)) as cnt_checkins from checkins
group by course_id
2. course_id๋ณ ์ธ์์ ๊ตฌํ๋ค.
select course_id, count(*) as cnt_total from orders
group by course_id
3. 1,2๋ฒ๊ณผ course์ title ์ ๋ณด๊ฐ ์๋ coursesํ ์ด๋ธ์ joinํ๋ค.
select *
from
(
select course_id, count(distinct(user_id)) as cnt_checkins
from checkins
group by course_id
) a
inner join (
select course_title, 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
4. join๋ ๊ฐ ํ ์ด๋ธ์ ๋ณ์นญ์ ์ด์ฉํด select ํ๊ณ ์ถ์ ๋ฐ์ดํฐ๋ค์ select ํ๋ค.
select c.title,
a.cnt_checkins,
b.cnt_total,
round(a.cnt_checkins/b.cnt_total,4) as ratio
from
(
select course_id, count(distinct(user_id)) as cnt_checkins
from checkins
group by course_id
) a
inner join (
select course_title, 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
๐ฅ With์
with ์ ์ ์ด์ฉํด subquery๋ฅผ ๊ฐ์ ํ ์ด๋ธ๋ช ์ผ๋ก ์ฌ์ฉํ ์ ์๋ค.
with table1 as (subquery1), table2 as (subquery2) ....
์ฌ์ฉ ์์
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(๋ฌธ์์ด, ์ชผ๊ฐ๊ณ ์ถ์ ๊ธฐ์ค ๋ฌธ์์ด, ๊ฐ์ง๊ณ ์ฌ ๋ฌธ์์ด ์์น)
- ์ด๋ฉ์ผ์์ ์์ด๋๋ง ๊ฐ์ ธ์ค๊ธฐ
select user_id, email, SUBSTRING_INDEX(email, '@', 1) from users
- ์ด๋ฉ์ผ์์ ๋๋ฉ์ธ๋ง ๊ฐ์ ธ์ค๊ธฐ
select user_id, email, SUBSTRING_INDEX(email, '@', -1) from users
๋ฌธ์์ด ์ผ๋ถ๋ง ์ถ๋ ฅ
substring(๋ฌธ์์ด, ๊ฐ์ ธ์ฌ ๋ฌธ์์ด ์ฒซ ๊ธ์ ์์น, ๋ช๊ฐ์ ๊ธ์๋ฅผ ์ถ๋ ฅํ๊ณ ์ถ์์ง)
- ordersํ ์ด๋ธ์์ ๋ ์ง๊น์ง ์ถ๋ ฅํ๊ธฐ
select order_no, created_at, substring(created_at,1,10) as date from orders
๐ฅ Case
๊ฒฝ์ฐ(case)์ ๋ฐ๋ผ ์ํ๋ ๊ฐ์ ์ ํ๋์ ์ถ๋ ฅํด๋ณด๊ธฐ
select ํ๋๋ช
, ํ๋๋ช
,
case
when ์กฐ๊ฑด1 then ์ถ๋ ฅ๊ฐ1
when ์กฐ๊ฑด2 then ์ถ๋ ฅ๊ฐ2
.
.
.
else ์กฐ๊ฑดn ์ถ๋ ฅ๊ฐn
end as ๋ณ์นญ
from ํ
์ด๋ธ๋ช
์ฌ์ฉ์์
- point_usersํ ์ด๋ธ์์ 10000์ ๋ณด๋ค ๋์ ํฌ์ธํธ๋ฅผ ๊ฐ์ง๊ณ ์์ผ๋ฉด '์ํ๊ณ ์์ด์!', ํ๊ท ๋ณด๋ค ๋ฎ์ผ๋ฉด 'ํ๋ด์!' ๋ผ๊ณ ํ์ํ๊ณ , ์ด ์๋ก์ด ํ๋๋ช ์ '๊ตฌ๋ถ'์ด๋ค.
select pu.point_user_id, pu.point,
case
when pu.point > 10000 then '์ ํ๊ณ ์์ด์!'
else 'ํ๋ด์!'
END as '๊ตฌ๋ถ'
from point_users pu;
- point_users ํ ์ด๋ธ์์ ํฌ์ธํธ๊ฐ 5์ฒ ๋ฏธ๋ง, 5์ฒ ์ด์, 1๋ง ์ด์์ธ user๋ค์ ์ ํต๊ณ๋ด๊ธฐ
with table1 as (
select pu.point_user_id, pu.point,
case
when pu.point > 10000 then '1๋ง ์ด์'
when pu.point > 5000 then '5์ฒ ์ด์'
else '5์ฒ ๋ฏธ๋ง'
END as level
from point_users pu
)
select level, count(*) as cnt from table1
group by level
Source
์คํ๋ฅดํ ์ฝ๋ฉํด๋ฝ ๋ด์ผ๋ฐฐ์๋จ ์์ ๋ณด๋จ ์ฌ์ด SQL 4์ฃผ์ฐจ
'Database > SQL' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[MySQL] ๋ฐ์ดํฐ ๋ฒ ์ด์ค ์ธ๋ฑ์ค (0) | 2022.10.08 |
---|---|
[MySQL] DB, Table, Data, Column ์์ฑ, ์กฐํ, ์์ , ์ญ์ (0) | 2022.09.26 |
[MySQL] [์คํ๋ฅดํ์ฝ๋ฉํด๋ฝ SQL] Join, Union (0) | 2022.07.16 |
[MySQL] [์คํ๋ฅดํ์ฝ๋ฉํด๋ฝ SQL] Group by, Order by (0) | 2022.07.09 |
[MySQL] [์คํ๋ฅดํ์ฝ๋ฉํด๋ฝ SQL] Select, Where (0) | 2022.07.01 |