๋ค๋ฅธ SQL ์์ ๋ค์ด์๋ SELECT
MySQL์ ์๋ธ์ฟผ๋ฆฌ๊ฐ ๋ฐํํ๋ ํํ๊ฐ 4์ข ๋ฅ
- scalar(๊ฐ 1๊ฐ)
- row(ํ 1๊ฐ)
- column(์ด 1๊ฐ = ๋ฆฌ์คํธ)
- table(ํ)
<Scalar Subquery; ๋ ๋ฆฝ๋ ๊ฐ1๊ฐ๋ก ๋ฐํ>
Q. ํ๊ท ๋ณด๋ค ๋น์ผ ๊ฐ์ข ์ฐพ๊ธฐ
(1. ์๋ธ ์ฟผ๋ฆฌ)๋ชจ๋ ๊ฐ์ข ํ๊ท ๊ตฌํ๊ธฐ (2. ๋ฐ๊นฅ ์ฟผ๋ฆฌ) ๊ทธ๊ฒ๋ณด๋ค ๋น์ผ ๊ฐ์ข ์ฐพ๊ธฐ
SELECT
course_id,
course_name,
list_price
FROM basic.courses
WHERE list_price > (SELECT AVG(list_price) FROM basic.courses)
ORDER BY list_price DESC;
- (SELECT AVG(list_price) FROM basic.courses) = 120428.5714
- ๋ฐ๊นฅ ์ฟผ๋ฆฌ์ ์ฐ๋๋์ง ์์ ๋ ๋ฆฝ๋ ๊ฐ ์ถ๋ ฅ - ์๋ธ ์ฟผ๋ฆฌ ๋จ๋ ์คํ ์, ์๋ํจ.
- where์๋ ์ง๊ณํจ์ ์ฌ์ฉ ๋ถ๊ฐ, ์๋ธ์ฟผ๋ฆฌ ํํ ์ด์ฉ.
<Column Subquery; ์ด1๊ฐ, ๋ฆฌ์คํธ>
IN()
Q. 'sql ์นดํ ๊ณ ๋ฆฌ ๊ฐ์ข'๋ฅผ ์ ์ฒญํ ๋ด์ญ๋ง ๋ณด๊ธฐ
(1. ์๋ธ ์ฟผ๋ฆฌ) T.courses - C.category = 'sql'
(2. ๋ฐ๊นฅ ์ฟผ๋ฆฌ) T.enrollments
- (T)courses์ (T)enrollments์ ๊ณตํต ์ปฌ๋ผ: course_id
(*๊ฒฐ๊ตญ ๋ ๊ฐ์ ์ฟผ๋ฆฌ๊ฐ ์ฐ๋๋๋ ๊ฒ - โญ๏ธ ๊ณตํต ์ปฌ๋ผ์ ์ฐ๋ํด์ฃผ๋ ๊ฒ ์ค์) - IN ( ... ) ์์ชฝ์ ํ ์ปฌ๋ผ์ง๋ฆฌ ๋ฆฌ์คํธ๊ฐ ๋์ค๋ฉด ์ฑ๊ณต
SELECT enrollment_id, final_price
FROM basic.enrollments
where course_id IN
(
SELECT course_id -- ํ ์ค์ง๋ฆฌ ์ปฌ๋ผ ์ถ๋ ฅ
FROM basic.courses
where category = 'sql'
);
- ์๋ธ์ฟผ๋ฆฌ ์ปฌ๋ผ์ ์ฌ๋ฌ ๊ฐ ์ถ๋ ฅํ๋ฉด, ์๋ฌ.

<Table Subquery; ํ>
EXISTS / NOT EXISTS (“ํ ๋ฒ์ด๋ผ๋ ์๋ค / ํ ๋ฒ๋ ์๋ค” ์ฐพ๊ธฐ์ ์ฉ์ด)
- ์๋ธ์ฟผ๋ฆฌ์ SELECT๋ ๊ฒฐ๊ณผ์ ๋ฌด๊ด (select *, select 1, select 5 ๋ฑ ์ด๋ค ๊ฑธ ์จ๋ ๊ฒฐ๊ณผ ๋์ผ)
- ๋ ํ ์ด๋ธ์ ๊ณตํต ์ปฌ๋ผ์ where์์ ๋ฌถ์ด์ค. (= ๋ ํ ์ด๋ธ์ ๋ชจ๋ ์กด์ฌํ๋ ํ ์ฐพ๊ธฐ)
- exists: ๋งค์นญ๋๋ ๊ฒ ์๋ ๊ฒ / not exists: ๋งค์นญ๋์ง ์๋ ๊ฒ.
- True/False ๊ฐ์ ๋ฐํํ๋ ๊ฑฐ์ฌ์, ์๋ธ ์ฟผ๋ฆฌ ๋ด ๊ฒฐ๊ณผ ํ์ ๋ฐ์ผ๋ก ๊ฐ์ ธ์ฌ ์ ์์.
Q. ์๊ฐ์ ์ฒญ์ "ํ ๋ฒ์ด๋ผ๋ ํ / ํ ๋ฒ๋ ์ ํ" ํ์ ์ฐพ๊ธฐ
(1. ์๋ธ ์ฟผ๋ฆฌ) (T)enrollments โฏ (T)students
(2. ๋ฐ๊นฅ ์ฟผ๋ฆฌ) (T)students ์ถ๋ ฅ
-- ํ ๋ฒ์ด๋ผ๋ ํ ํ์ ์ฐพ๊ธฐ
SELECT s.student_id,
s.student_name
FROM basic.students s
where exists
(
select *
from basic.enrollments e
where e.student_id=s.student_id
);
-- ํ ๋ฒ๋ ์ ํ ํ์ ์ฐพ๊ธฐ
SELECT s.student_id,
s.student_name
FROM basic.students s
where not exists
(
select *
from basic.enrollments e
where e.student_id=s.student_id
);
<FROM ์๋ธ์ฟผ๋ฆฌ(ํ์ ํ
์ด๋ธ)>
From์์ ์ฌ์ฉํ ํ
์ด๋ธ์ ์๋ธ์ฟผ๋ฆฌ๋ก ์์ฑ
- JOIN์์ N์ชฝ ํ ์ด๋ธ์ '์ฐ์ ์์ฝ'ํ์ฌ ์ฌ์ฉํ๋ ๊ฐ๋
- FROM ํ ์ด๋ธ ์ด๋ฏธ ํํฐ๋ง๋ ์ํ → ์ต์ข ๊ฒฐ๊ณผ์์ ํ์ด ๋์ด๋์ง ์์.
- AS ๋ณ์นญ ํ์
Q. ๊ฐ์ข๋ณ ์ ์ฒญ ๊ฑด์ "์์ฝํ" ๋ง๋ค๊ธฐ
(1. ์๋ธ ์ฟผ๋ฆฌ) ์ ์ฒญ ๊ฑด์ ํ ์ด๋ธ ๋ง๋ค๊ธฐ
(2. ๋ฐ๊นฅ ์ฟผ๋ฆฌ) ๊ฐ์ข๋ณ๋ก ์ถ๋ ฅํ๊ธฐ
-- ๊ฐ์ข๋ณ
SELECT c.course_id,
c.course_name,
ifnull(enr.enroll_cnt,0)
from basic.courses c
left join (-- ์ ์ฒญ๊ฑด์
select course_id,
count(*) as enroll_cnt
from basic.enrollments
group by course_id
) as enr
ON c.course_id=enr.course_id;
- ์๋ธ์ฟผ๋ฆฌ ์์์ course_id๋ก ์ด๋ฏธ group byํ๊ธฐ ๋๋ฌธ์,
๋ฐ๊นฅ ์ฟผ๋ฆฌ์์ ์ถ๊ฐ๋ก ๊ทธ๋ฃนํํ ํ์ X
<CTE (WITH) : ์ด๋ฆ ๋ถ์ธ ํ์ํ ์ด๋ธ>
- ์ด๋ฆ์ด ์๋ ์์ ๊ฒฐ๊ณผ
WITH ์ด๋ฆ AS (
SELECT ...
)
SELECT *
FROM ์ด๋ฆ;
Q. "active ์ ์ฒญ๋ง" ๋จผ์ ๊ณจ๋ผ์ ๋ณด๊ธฐ
(1. CTE ์๋ธ ์ฟผ๋ฆฌ) active ๊ฒฐ๊ณผ๋ง ๋ฝ์์ ์์ํ ๋ง๋ค๊ธฐ
(2. ๋ฐ๊นฅ ์ฟผ๋ฆฌ) ์์ํ์์ ์ถ๋ ฅํ๊ธฐ
WITH active_enrollment as
(-- CTE
select enrollment_id,
student_id,
course_id,
enroll_date
from basic.enrollments
where enrollment_status = 'active'
)
-- ๋ฐ๊นฅ ์ฟผ๋ฆฌ
select *
from active_enrollment;
<CTE (WITH) + CASE ๊ฐ์ด ์ฌ์ฉํ๊ธฐ>
- CTE ํ์ํ ์ด๋ธ ์์ฑ
- 'CTE' JOIN '์๋ ํ ์ด๋ธ(case when ์ฌ์ฉ)' => ๊ฒฐ๊ณผ
Q. ํ์๋ณ ์ ์ฒญ๊ฑด์ ๊ตฌํ๊ธฐ + ๊ฑด์์ ๋ฐ๋ฅธ ๋ผ๋ฒจ๋ง
(1. CTE) ํ์ํ ์ด๋ธ: ํ์๋ณ ์ ์ฒญ๊ฑด์
(2. JOIN) ํ์๋ณ join ์ ์ฒญ๊ฑด์(→CTE)
+ ๋ผ๋ฒจ๋ง case when ์กฐ๊ฑด
WITH enr_by_stu AS (
SELECT student_id,
count(*) AS enroll_cnt
FROM basic.enrollments
GROUP BY student_id
)
SELECT s.student_id,
s.student_name,
ifnull(enroll_cnt, 0) AS enroll_cnt,
CASE WHEN ifnull(e.enroll_cnt, 0) = 0 THEN 'no_enroll'
WHEN e.enroll_cnt >= 1 THEN 'has_enroll'
END AS enroll_flag
FROM basic.students s
LEFT JOIN enr_by_stu e
ON s.student_id=e.student_id;
<์๊ด ์๋ธ์ฟผ๋ฆฌ(Correlated Subquery)>
: ์๋ธ์ฟผ๋ฆฌ ์์์ ๋ฐ๊นฅ ์ฟผ๋ฆฌ์ ํ ์ด๋ธ ์ปฌ๋ผ์ ์ฐธ์กฐํ๋ ์๋ธ์ฟผ๋ฆฌ
“๋ฐ๊นฅ ์ฟผ๋ฆฌ์์ ํ ํ์ ๊บผ๋ผ ๋๋ง๋ค, ๊ทธ ํ์ ๋ง์ถฐ์ ์์ชฝ ์ฟผ๋ฆฌ๊ฐ ๊ณ์ฐ๋๋ค”
- ๋น์๊ด ์๋ธ์ฟผ๋ฆฌ: ์๋ธ์ฟผ๋ฆฌ์ ๊ฒฐ๊ณผ๊ฐ ์กฐ๊ฑด์ผ๋ก ์ฌ์ฉ๋๋ค.
- ์๊ด ์๋ธ์ฟผ๋ฆฌ: ๋ฐ๊นฅ ์ฟผ๋ฆฌ์ ํ ํ์ ์ถ๋ ฅํ ๋๋ง๋ค, ๊ทธ ํ์ ๋งค์นญ๋๋ ์๋ธ์ฟผ๋ฆฌ๊ฐ ์ถ๋ ฅ๋๋ค.
SELECT
s.student_id,
s.student_name,
(
SELECT COUNT(*)
FROM basic.enrollments e
WHERE e.student_id = s.student_id
) AS enroll_cnt
FROM basic.students s
ORDER BY s.student_id;

'์คํ๋ฅดํ ๋ด์ผ๋ฐฐ์์บ ํ(25.12.01~)' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
| ์คํ๋ฅดํ ๋ด์ผ๋ฐฐ์์บ ํ_๋ณธ์บ ํ_data11๊ธฐ ๊น์ ์_TIL_Day 7 (0) | 2026.01.01 |
|---|---|
| [SQL ์ฝ๋์นดํ] ๋ ๋ฒจ 1 / 1~10 (0) | 2025.12.31 |
| ์คํ๋ฅดํ ๋ด์ผ๋ฐฐ์์บ ํ_๋ณธ์บ ํ_data11๊ธฐ ๊น์ ์_TIL_Day 6 (2) | 2025.12.30 |
| [๊ฐ๋ ์ ๋ฆฌ] Having + Subquery (0) | 2025.12.29 |
| ์คํ๋ฅดํ ๋ด์ผ๋ฐฐ์์บ ํ_๋ณธ์บ ํ_data11๊ธฐ ๊น์ ์_TIL_Day 5 (0) | 2025.12.29 |