์ด์ ๋ ธ์ ๋ธ๋ก๊ทธ์ SQL Tutorial (2021.01.17)๋ก๋ถํฐ ๋ง์ด๊ทธ๋ ์ด์ ๋ ๊ธ์ ๋๋ค.
Aggreate Functions
aggregate functions(์ง๊ณ ํจ์)์ ํญ์ ์ฌ์ฉํ๊ฒ ๋ ๊ฒ์ด๋ ์ต์ํด์ ธ์ผ ํ๋ค. arithmetic operators๋ ํ ํ์ ์ด๊ฐ์ ์ฐ์ฐ๋ง ์ํํ์ง๋ง, aggregate functions์ ํ ์ ์ฒด์ ๊ฑธ์ณ์ ์ํํ ์ ์๋ค.
COUNT
Counting all rows
COUNT ๋ ํน์ ์ด์ ์ซ์๋ฅผ ์ธ๋ฆฌ๋ aggregate function์ด๋ค.. ์๋์ ๋ SQL ๋ฌธ์ ๊ฒฐ๊ณผ๋ ๊ฐ๋ค.
SELECT COUNT(*)
FROM tutorial.aapl_historical_stock_price
SELECT *
FROM tutorial.aapl_historical_stock_price
Counting individual columns
์๋์ ์ฝ๋๋ high ์ด์ด is not null ์ธ ๋ชจ๋ ํ์ ์ธ๋ฆด ๊ฒ์ด๋ค. ๊ฐ๊ฐ์ ๊ณ ์ ํ ๊ฐ๋ค์ ์ ๊ฒฝ์ฐ์ง ์๋๋ค. ๋๋ฌธ์ ๊ฐ์ ํ์ ์ ์๊ด์์ด ์ํ๊ฐ๋ฅํ๋ค.
SELECT COUNT(high)
FROM tutorial.aapl_historical_stock_price
๊ฒฐ๊ณผ๊ฐ COUNT(*) ๋ณด๋ค ์ ์ ๊ฒ์ ํ์ธํ ์ ์๋ค. high ์ ์ผ๋ถ๋ง์ด null ์ด๊ธฐ ๋๋ฌธ์ด๋ค. SQL์ ์ฌ์ฉํ๋ฉด์ ์์ฐ์ค๋ฝ๊ฒ ๋ฐ์ํ๋ null ํ์ ์์ฃผ ๋ณด๊ฒ ๋ ๊ฒ์ด๋ค.
์๋ฅผ๋ค์ด, ์ด๋ฉ์ผ ์ฃผ์์ ์ ์ ๊ฐ ์ด๋ฉ์ผ์ ์ฝ์ ์๊ฐ๊ณผ ๋ ์ง์ ์ด์ด ํฌํจ๋ ์ ์ ํ ์ด๋ธ์ด ์๋ค๊ณ ๊ฐ์ ํด๋ณด์. ๋ช๋ช์ ์ฌ๋๋ค์ด ์ด๋ฉ์ผ์ ํ์ธํ์ง ์์๋ค๋ฉด, ์๊ฐ๊ณผ ๋ ์ง ํ๋๋ null์ด ๋ ๊ฒ์ด๋ค.
๊ฒฐ๊ณผ์ ์ด์ ํค๋๊ฐ ๊ทธ๋ฅ "high"๋ก ๋์ด์๋ค. ๋๋ฌธ์ AS ๋ฅผ ์จ์ ๋ณ๋๋ก ๋ช ๋ช ํ๋ ๊ฒ์ด ์ข๋ค. ๊ธฐ๋ณธ์ ์ผ๋ก ์๋ฌธ์์ ๊ณต๋ฐฑ์ด ์๋ ๊ฒ์ด ์์น์ด์ง๋ง, ํ์ํ๋ค๋ฉด " " ์ ์ฌ์ฉํ๋ฉด ์์ ๋กญ๊ฒ ๋ช ๋ช ๊ฐ๋ฅํ๋ค.
SUM
The SQL SUM function
SUM ์ ์ฃผ์ด์ง ์ด๋ค์ ๊ฐ์ ํฉ์ ๊ตฌํ๋ค. COUNT ์ ๋ฌ๋ฆฌ, SUM ์ ์ซ์๊ฐ์ ํฌํจํ ์ด์๋ง ์ํํ ์ ์๋ค. ์๋์ ์ฟผ๋ฆฌ๋ volumn ์ ํฉ์ ๊ตฌํ๋ค.
SELECT SUM(volume)
FROM tutorial.aapl_historical_stock_price
๊ธฐ์ตํด์ผํ๋ ๊ฒ์ : aggregator๋ค์ ์์ง์ผ๋ก๋ง ์ง๊ณํ๋ค. ํ ํ์์์ ๊ณ์ฐ์ ์ํํ๊ณ ์ถ์ผ๋ฉด ๋จ์ํ arithmetic ์ ์ฌ์ฉํด๋ผ.
SUM ์ null์ 0์ผ๋ก ์ฒ๋ฆฌํ๊ธฐ ๋๋ฌธ์, null๋ก ์ธํ ๋ฌธ์ ์ ๋ํด์ ์ ๊ฒฝ์ธ ํ์ ์๋ค.
MIN MAX
MIN MAX ๋ ํน์ ์ด์ ๊ฐ๋ค ์ค ์ต์, ์ต๋๊ฐ์ ๋ฐํํ๋ค.
COUNT ์ ๊ฐ์ด ์ซ์๊ฐ ์๋ ์ด๋ค์๋ ์ฌ์ฉํ ์ ์๋ค. ์ด์ ๊ฐํ์ ์ ๋ฐ๋ผ์, MIN ์ ์ต์ ๊ฐ, ๊ฐ์ฅ ์ด๋ฅธ ๋ ์ง, ์ซ์๊ฐ ์๋ ๊ฐ์ ๊ฐ๋ฅํ ์ํ๋ฒณ์ ์ผ๋ก "A"์ ๊ฐ๊น์ด ๊ฐ์ ๋ฐํํ๋ฉฐ MAX ๋ ๊ทธ ๋ฐ๋๋ค.
AVG
AVG ๋ ํน์ ์ด์ ๊ฐ์ ํ๊ท ์ ๊ณ์ฐํ์ฌ ๋ฐํํ๋ค. ๋จ 2๊ฐ์ง ํ๊ณ๊ฐ ์๋ค.
- ์ซ์์ธ ๊ฐ์ ๊ฐ์ง ์ด์๋ง ์ฌ์ฉ ๊ฐ๋ฅ
- null์ ๋ฌด์ํ๋ค. (0์ผ๋ก ์ฒ๋ฆฌํ๋ ๊ฒ์ด ์๋๋ผ ๋ฌด์)
๋ฐ๋ผ์ ์๋์ SQL๋ฌธ๋ค์ ๊ฐ์ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํ๋ค.
SELECT AVG(high)
FROM tutorial.aapl_historical_stock_price
WHERE high IS NOT NULL
SELECT AVG(high)
FROM tutorial.aapl_historical_stock_price
null์ 0์ผ๋ก ์ฒ๋ฆฌํ๊ณ ์ถ์ ๊ฒฝ์ฐ, CASE ๋ฅผ ์ฌ์ฉํ๋ฉด ๋๋ค.
GROUP BY
The SQL GROUP BY clause
COUNT AVG SUM ์ ์ ์ฒด ํ ์ด๋ธ์ ๊ฑธ์ณ ์ํํ๋ค๋ ๊ณตํต์ ์ด ์๋ค. ํ์ง๋ง ํ ์ด๋ธ์ ์ผ๋ถ์์๋ง ์ํํ๊ธธ ์ํ๋ค๋ฉด? ์๋ฅผ๋ค์ด, ์ฐ๋๋ณ๋ก ์ ์ฒด ๊ฐ์ ์นด์ดํธํ๊ณ ์ถ์ ์ ์๋ค.
์ด๋ฐ ๊ฒฝ์ฐ, GROUP BY ๊ฐ ํ์ํ๋ค. GROUP BY ๋ ๋ฐ์ดํฐ๋ฅผ ๊ทธ๋ฃน์ผ๋ก ๋ถ๋ฆฌํ ์ ์์ผ๋ฉฐ, ๋ฐ์ดํฐ๋ ์๋ก ๋ ๋ฆฝ์ ์ผ๋ก ์ง๊ณํ๋ค.
SELECT year,
COUNT(*) AS count
FROM tutorial.aapl_historical_stock_price
GROUP BY year
์ฌ๋ฌ ๊ฐ์ ์ด๋ก ๊ทธ๋ฃนํํ ์ ๋ ์๋ค. ํ์ง๋ง ์ด์ ์ด๋ฆ์ผ๋ก ์๋ก ๊ตฌ๋ณ์์ผ ์ค์ผํ๋ค.
SELECT year,
month,
COUNT(*) AS count
FROM tutorial.aapl_historical_stock_price
GROUP By year, month
Using GROUP BY with ORDER BY
GROUP BY ์ ์์ ์ด ์ด๋ฆ์ ์์๋ ์ค์ํ์ง ์๋ค. (๊ฒฐ๊ณผ์ ์ํฅ์ ๋ฏธ์น์ง ์๋๋ค) ์ด๋ป๊ฒ ์ง๊ณ๋ ์ง๋ฅผ ์ปจํธ๋กคํ๊ณ ์ถ๋ค๋ฉด ORDER BY ๋ฅผ ์ฌ์ฉํด๋ผ.
SELECT year,
month,
COUNT(*) AS count
FROM tutorial.aapl_historical_stock_price
GROUP BY year, month
ORDER BY month, year
Using GROUP BY with LIMIT
SQL์ LIMIT ๋ฅผ ์ํํ๊ธฐ ์ ์ ์ง๊ณ(aggregation)์ ์ํํ๋ค๋ ๊ฒ์ ์๊ณ ์์ด์ผํฉ๋๋ค. GROUP BY ๋ฅผ ์ํํ ๊ทธ๋ฃนํํ ๊ฒฐ๊ณผ์ ํ์ด LIMIT ์๋ณด๋ค ๋ง์๊ฒฝ์ฐ, SQL์ ์ง๊ณ๋ฅผ ๋ชจ๋ ๊ณ์ฐํ์ฌ ๊ฒฐ๊ณผ๋ฅผ ์ฐ์ถํ ์ดํ, LIMIT ์ ๋ฐ๋ผ์ ๊ฒฐ๊ณผ์ฐฝ์์ ์๋ตํ๊ธฐ๋ง ํฉ๋๋ค. (๊ณ์ฐ์์ฒด๊ฐ ์๋ต๋์ง ์์ต๋๋ค.)
์ฌ๋ฐ๋ฅธ ์ง๊ณ ๊ฒฐ๊ณผ๋ฅผ ์ํด์๋ ์ด๋ ๊ฒ ๋์ํด์ผ ํฉ๋๋ค. ๊ณ์ฐ๋๋ ์ด์ ์๊น์ง LIMIT ๋๋ค๋ฉด, ํ๋ฆฐ ๊ฒฐ๊ณผ๊ฐ ๋์ฌ ๊ฒ์ ๋๋ค.
HAVING
The SQL HAVING clause
์ข ์ข GROUP BY ์ผ๋ก๋ ์ถฉ๋ถํ์ง ์์ dataset๋ฅผ ๋ง๋ ๊ฒ์ด๋ค. month๋ก ์ง๊ณ๋ ๋ฐ์ดํฐ๋ฅผ ์๋ก ๋ค์ด๋ณด์. dataset์๋ ์๋ง์ month๊ฐ ์์ํ ๋ฐ, ๊ทธ ์ค AAPL ์ฃผ์์ด $400/share ์ธ ๊ฒฝ์ฐ๋ง ์ฐพ๊ณ ์ถ๋ค๋ฉด ์ด๋ป๊ฒ ํด์ผํ ๊น? WHERE ์ ์ ์ง๊ณ๋ ์ด์ ํํฐ๋งํ๋๋ฐ ์ฌ์ฉ๋์ง ์๊ธฐ ๋๋ฌธ์ ์ฌ๊ธฐ์ ์ฌ์ฉํ ์ ์๋ค.
SELECT year,
month,
MAX(high) AS month_high
FROM tutorial.aapl_historical_stock_price
GROUP BY year, month
HAVING MAX(high) > 400
ORDER BY year, month
๐ `HAVING` ์ ์ง๊ณ๋ ์ฟผ๋ฆฌ๋ฅผ ํํฐ๋งํ๊ธฐ์ํ "๊น๋ํ" ๋ฐฉ๋ฒ์ด๋ค. ํ์ง๋ง, ๋ณดํต์ subquery๋ฅผ ์ด์ฉํ๋ค.
Query clause order
- SELECT
- FROM
- WHERE
- GROUP BY
- HAVING
- ORDER BY
CASE
The SQL CASE statement
CASE ๋ if/then ๋ก์ง์ ์ฒ๋ฆฌํ๋ค. WHEN ๊ณผ THEN ์ผ๋ก ์ด๋ฌ์ง ์ต์ ํ ๊ฐ์ ์ง์ผ๋ก ๊ตฌ์ฑ๋๊ณ , ๋ชจ๋ CASE ๋ฌธ์ ๋ง์ง๋ง์ END ๊ฐ ์์ผํ๋ค. ELSE ๋ ์ ํ ์ฌํญ์ด๋ฉฐ, WHEN/THEN ์ ํด๋นํ์ง ์๋ ๊ฒ๋ค์๊ฒ ๊ฐ์ ์ค ์ ์๋ค.
SELECT player_name,
year,
CASE WHEN year = 'SR' THEN 'yes'
ELSE NULL
END AS is_a_senior
FROM benn.college_football_players
Adding multiple conditions to a CASE statement
CASE ์ WHEN/THEN ์ ์์์๋ถํฐ ์คํ๋๋ฏ๋ก ์๋์ ๊ฐ์ด ์กฐ๊ฑด์ ๋์ดํ๋ค๋ฉด ๋ฒ์์ ๋ฐ๋ฅธ ์กฐ๊ฑด์ ์ ์ฉ์ํฌ ์ ์๋ค.
SELECT player_name,
weight,
CASE WHEN weight > 250 THEN 'over 250'
WHEN weight > 200 THEN '201~250'
WHEN weight > 175 THEN '176~200'
ELSE '175 or under' END AS weight_group
FROM benn.college_football_players
์กฐ๊ฑด์ ๊ฒน์น์ง์๊ณ ๋ช ํํ ๋ฒ์๋ฅผ ์ ์ํ ์ ๋ ์๋ค. ์ด๋๋ AND OR ๋ฅผ ์ฌ์ฉํ๋ฉด ๋๋ค.
SELECT player_name,
weight,
CASE WHEN weight > 250 THEN 'over 250'
WHEN weight > 200 AND weight <= 250 THEN '201~250'
WHEN weight > 175 AND weight <= 200 THEN '176~200'
ELSE '175 or under' END AS weight_group
FROM benn.college_football_players
A quick review of CASE basics
- CASE ๋ ์ธ์ ๋ SELECT ์ ์์ ๋ค์ด๊ฐ๋ค.
- CASE ๋ WHEN THEN END ๋ก ์ด๋ฃจ์ด์ง๋ฉฐ ์ ํ์ ์ธ ELSE ๋ ์๋ค.
- WHEN ๊ณผ THEN ์ฌ์ด์์ WHERE ๊ฐ์ ์ด๋ค ์กฐ๊ฑด ์ฐ์ฐ์๋ก๋ ๋ค์ํ ์กฐ๊ฑด๋ฌธ์ ๋ง๋ค ์ ์๋ค. AND OR ๋ฅผ ์ฌ์ฉํด์ ์ฌ๋ฌ ์กฐ๊ฑด๋ฌธ์ ๋ฌถ์ ์๋ ์๋ค.
- WHEN ์ผ๋ก ์ฌ๋ฌ ์กฐ๊ฑด๋ฌธ์ ํฌํจ์ํฌ ์ ์๊ณ , ELSE ๋ก ๋ช ์๋์ง ์์ ์กฐ๊ฑด๋ค์ ์ฒ๋ฆฌํ ์ ์๋ค.
Using CASE with aggregate functions
CASE ๋ aggregate functions ๊ณผ ํจ๊ป ์ฌ์ฉํจ์ผ๋ก์ ๋ ๋ณต์กํ๊ณ ์ ์ฉํ๊ฒ ์ธ ์ ์๋ค. ์๋ฅผ๋ค์ด, ํน์ ์กฐ๊ฑด์ ์ฑ์ด ํ๋ง์ ์ํ๋ค๋ฉด, COUNT ๋ null์ ๋ฌด์ํ๊ธฐ ๋๋ฌธ์ CASE ๋ฅผ ์ฌ์ฉํด์ ์กฐ๊ฑด์ ํ๊ฐํ๊ณ ๊ฐ์ด ๊ฒฐ๊ณผ์ ๋ฐ๋ฅธ null ํน์ non-null ๊ฐ์ ๋์ถํ๋ค.
DISTINCT
Using SQL DISTINCT from viewing unique values
ํน์ ์ด์์ ์๋ ์ ๋ํฌํ ๊ฐ๋ง์ ๋ณด๊ธฐ์ํด์ SELECT DISTINCT ๋ฌธ๋ฒ์ ์ฐ๋ฉด ๋๋ค.
SELECT DISTINCT year, month
FROM tutorial.aapl_historical_stock_price
DISTINCT ๋ ์๋ก์ด data set์ ํ์ ํ ๋ ์ฐ์ธ๋ค. ๊ฐ ์ด์ ์ ๋ํฌํ ๊ฐ๋ค์ ์ดํด๋ณด๊ณ ์ด๋ป๊ฒ ๋ฐ์ดํฐ๋ฅผ ํํฐ๋งํ๊ณ ๊ทธ๋ฃนํํ ๊ฑด์ง ์ ๊ทผํ๋ค.
Using DISTINCT in aggregations
์ง๊ณํ ๋๋ ํจ๊ป ์ฌ์ฉํ ์ ์๋๋ฐ, ๋๋ถ๋ถ COUNT ์ ํจ๊ป ์ธ ๊ฒ์ด๋ค.
SELECT COUNT(DISTINCT month) AS unique_months
FROM tutorial.aapl_historical_stock_price
์ด์ธ์๋ aggregation์์ ๊ทธ๋ค์ง ์ฌ์ฉ๋ ์ผ์ด ์์ต๋๋ค. SUM, AVG, MAX, MIN ๋ฑ๋ฑ์ ์ ๋ํฌํ ๊ฐ๋ค์ ํ์๋ก ํ์ง ์์ต๋๋ค.
DISTINCT performance
DISTINCT ์ ์ฌ์ฉํ๋ฉด (ํนํ ์ง๊ณ์์) ์ฟผ๋ฆฌ๊ฐ ์๋นํ ๋๋ ค์ง ์ ์์ต๋๋ค. ์ด์ ๋ํด์ ๋ค์์ ์์ธํ ๋ค๋ฃฐ ๊ฒ ์ ๋๋ค.
Joins
JOIN
์ง๊ธ๊น์ง๋ ํ ๋ฒ์ ํ ํ ์ด๋ธ์ ๋ํ ์ํ ํ๋ค. ํ์ง๋ง SQL์ ์ง์ ํ ๊ฐ์ ์ ํ๋ฒ์ ์ฌ๋ฌ ๊ฐ์ ํ ์ด๋ธ๋ก๋ถํฐ ๋ฐ์ดํฐ ์ฒ๋ฆฌ๋ฅผ ์ํํ๋ ๊ฒ ์ด๋ค. ์ง๋ ์์ ๋ค๊น์ง ์ฌ์ฉํ ํ ์ด๋ธ์ ๊ด๊ณํ DB์์์ ์คํค๋ง์ ์ผ๋ถ๋ค. ๊ด๊ณํ DB๋ ํ ์ด๋ธ๋ผ๋ฆฌ ์๋ก ๊ด๊ณ๋์ด ์์ผ๋ฉฐ, ์ ๋ณด๊ฐ ์ฌ๋ฌ ํ ์ด๋ธ๋ค๊ณผ ์ฝ๊ฒ ํฉ์ณ์ง๊ธฐ ์ํ ๊ณตํต๋ ์๋ณ์๊ฐ ์๋ค.
joins๊ฐ ๋ฌด์์ด๊ฐ ๋ญ๊ฐ ์ ์ฉํ์ง ์ดํดํ๊ธฐ ์ํด์๋ ํธ์ํฐ๋ฅผ ๋ ์ฌ๋ ค ๋ณด์
ํธ์ํฐ๋ ๋ง์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํด์ผํ๋ค. ํธ์ํฐ์ ํ๋์ ํฐ ํ ์ด๋ธ์์ ๊ฐ ํ์ ํ๋์ ํธ์ํฐ๋ฅผ ๋ํ๋ผ ๊ฒ์ด๋ค. ๊ฐ ํธ์ํฐ์ ๋ณธ๋ฌธ์ ๋ด์ ์ด, ์์ฑ๋ ์๊ฐ์ ๋ด์ ์ด, ์์ฑํ ์ฌ๋์ ๋ด์ ์ด ๋ฑ๋ฑ์ด ํ์์ ์์ ๊ฒ์ด๋ค. ์ฌ๊ธฐ์ ํธ์์ ํ ์ฌ๋์ ์ฐพ์๋ด๋ ๊ฒ์ ์กฐ๊ธ ์ด๋ ต์ต๋๋ค. ํธ์ํฐ๊ฐ ํ ์ด๋ธ์ ๋ชจ๋ ๋ฐ์ดํฐ๋ฅผ ๋ค์๊ณผ ๊ฐ์ด ์ ์ฅํ๋ค๊ณ ๊ฐ์ ํด๋ด ์๋ค.
๋น์ ์ด ํธ์ํ ๋๋ง๋ค, ํธ์ํฐ๋ DB์ ๋น์ ๊ณผ ๋น์ ์ ํธ์์ ๋ํ ์ ๋ณด์ ํจ๊ป ์๋ก์ด ํ์ ์์ฑํฉ๋๋ค.
ํ์ง๋ง ์ฌ๊ธฐ์ ๋ฌธ์ ๊ฐ ๋ฐ์ํฉ๋๋ค. ๋น์ ์ ์๊ธฐ์๊ฐ๋ฅผ ๋ณ๊ฒฝํ ๋, ํธ์ํฐ๋ ํ ์ด๋ธ์ ์๋ ๋น์ ์ ํธ์ ํ๋ํ๋๋ง๋ค ์ ๋ณด๋ฅผ ๋ณ๊ฒฝํด์ค์ผ ํ๊ฒ ๋ฉ๋๋ค. ์ด๋ฐ ๊ตฌ์กฐ ๋๋ฌธ์, ํธ์ํฐ๋ ๋๊ฐ์ง ํ ์ด๋ธ๋ก ๊ตฌ์ฑ๋์ด์ผ ํฉ๋๋ค. ์ฒซ ๋ฒ์งธ ํ ์ด๋ธ - ์ ์ ํ ์ด๋ธ - ํ๋กํ ์ ๋ณด๋ฅผ ๊ฐ์ง๊ณ ์๊ณ ํ๋ง๋ค ์ ์ ๊ฐ ์ ์ฅ๋๋ค. ๋ ๋ฒ์ฌ ํ ์ด๋ธ - ํธ์ ํ ์ด๋ธ - ํธ์ ใ ใ ์ ๋ณด์ ํธ์ํฐ๋ฅผ ์์ฑํ ์ฌ๋์ username์ ํฌํจํ๋ค. ์ ์ ํ ์ด๋ธ์ username์ ํธ์ํฐ ํ ์ด๋ธ์ username์ matching/joining ํจ์ผ๋ก์, ํธ์ํฐ๋ ๋ชจ๋ ํธ์์ ํ๋กํ ์ ๋ณด๋ฅผ ์ฐ๊ฒฐํ ์ ์๋ค.
The anatomy of a join
SELECT teams.conference AS conference,
AVG(players.weight) AS average_weight
FROM benn.college_football_players players
JOIN benn.college_football_teams teams
ON teams.school_name = players.school_name
GROUP BY teams.conference
ORDER BY AVG(players.weight) DESC
Aliases in SQL
joins๋ฅผ ์ํํ ๋, ํ ์ด๋ธ์ ์ด๋ฆ์ aliases๋ฅผ ๋ถ์ด๋ ๊ฒ์ด ๊ฐ์ฅ ์ฌ์ด ๋ฐฉ๋ฒ์ด๋ค. ์๋ฌธ์๋ก ๊ตฌ์ฑํ๋ฉฐ ๊ณต๋ฐฑ๋์ ์ธ๋๋ฐ๋ฅผ ์ด๋ค. benn.college_football_players - players
JOIN and ON
ON ์ JOIN ๋ค์์ ์ค๋ฉฐ, FROM ์ ๋์จ ํ ์ด๋ธ๊ณผ JOIN ์ ๋์จ ํ ์ด๋ธ์ ๊ด๊ณ๋ฅผ ์ค๋ช ํฉ๋๋ค. ์์ SQL์ ํ์ด ์ค๋ช ํ๋ฉด ๋ค์๊ณผ ๊ฐ๋ค.
players ํ ์ด๋ธ์ ํ ์ค์์ school_name ํ๋์ teams ํ ์ด๋ธ ํ์ school_name ํ๋๊ฐ ๊ฐ์ ๊ฒฝ์ฐ ๋ ํ์ ์๋ก ์ฐ๊ฒฐํ๋ค.
์์ ๊ฐ์ด join์ผ๋ก ์๋ก์ดํ ์ด๋ธ์ ์์ฑํ๋ค๋ฉด, aggregate functions์ ์ฌ์ฉํ ์ ์๊ฒ ๋๋ค.
๋ค์๊ณผ ๊ฐ์ด ์คํํ๋ฉด ๋ ํ ์ด๋ธ์ ๋ชจ๋ ์ด์ ํ๋์ ํ ์ด๋ธ๋ก ์ถ๋ ฅํ๋ค. ๋ง์ฝ ํ๋์ ํ ์ด๋ธ์์๋ง ์ถ๋ ฅํ๊ณ ์ถ๋ค๋ฉด players.* ๋ฅผ SELECT ํ๋ฉด ๋๋ค.
SELECT *
FROM benn.college_football_players players
JOIN benn.college_football_teams teams
ON teams.school_name = players.school_name
INNER JOIN
INNER JOIN
players ํ ์ด๋ธ๊ณผ teams ํ ์ด๋ธ์ join ํด๋ณด์๋๋ฐ, ๋ง์ฝ ๋ฐ์ดํฐ๊ฐ ๊นจ๋ํ์ง ์๋ค๋ฉด? ๋ง์ฝ teams ํ ์ด๋ธ์ ๋๊ฐ์ ์ด๋ฆ์ ํ๊ต๊ฐ ์ฌ๋ฌ๊ฐ๋ผ๋ฉด? ๋ง์ฝ teams ํ ์ด๋ธ์ ์๋ ํ๊ต๊ฐ players ํ ์ด๋ธ์ ์๋ค๋ฉด?
์กฐ์ธ๋ ํ ์ด๋ธ ์ค ํ๋ ๋๋ ๋ ํ ์ด๋ธ ๋ชจ๋์ ์๋ ํ ์ด๋ธ๊ณผ ์ผ์นํ์ง ์๋ ํ์ ๊ฐ์ง ๊ฒฝ์ฐ๊ฐ ๋ง์ต๋๋ค. ์ด๋ฐ ๊ฒฝ์ฐ, inner join ์ธ์ง outer join ์ธ์ง์ ๋ฐ๋ผ ๋ฌ๋ผ์ง๋๋ค.
inner joins์ JOIN ํน์ INNER JOIN ์ด๋ผ๊ณ ์ ์ผ๋ฉฐ, ๋ชจ๋ ํ ์ด๋ธ์์ ON ์ ์กฐ๊ฑด์ ๋ง์กฑํ์ง ์๋ ํ๋ค์ ์ ๊ฑฐํฉ๋๋ค.
Joining tables with identical column names
๋ ํ ์ด๋ธ์ ์ฐ๊ฒฐํ ๋, ์์ชฝ ํ์ด๋ธ์ ๋๊ฐ์ ์ด๋ฆ์ ์ด์ ๊ฐ์ง๊ณ ์์ ์ ์๋ค. ์๋์ ๊ฐ์ ๊ฒฝ์ฐ, school_name ์ด๋ผ๊ณ ๋ถ๋ฆฌ๋ ์ด์ ์์ชฝ๋ค ๊ฐ์ง๊ณ ์๋ค.
SELECT players.*,
teams.*
FROM benn.college_football_players players
JOIN benn.college_football_teams teams
ON teams.school_name = players.school_name
๋ ์ด์ด ๊ฐ์ ๋ค๋ฅธ ๊ฐ์ ๊ฐ์ง๊ณ ์๋๋ผ๋ ๊ฒฐ๊ณผ๋ ํ๋์ ์ด๋ง ์ง์ํ๋ค. ์ด๋ฌํ ๊ฒฝ์ฐ๋ฅผ ๋ฐฉ์งํ๊ธฐ ์ํด ์ด์ ๊ฐ๊ฐ ์ด๋ฆ์ ์ง์ด์ฃผ๋ฉด ๋๋ค.
SELECT players.school_name AS players_school_name,
teams.school_name AS teams_school_name
FROM benn.college_football_players players
JOIN benn.college_football_teams teams
ON teams.school_name = players.school_name
Outer Joins
LEFT TABLE = FROM TABLE / RIGHT TABLE = JOIN TABLE
- LEFT JOIN ์ ์ผ์ชฝ ํ ์ด๋ธ ๋ฐํ (๋งค์นญ๋์ง ์์ ์ผ์ชฝ ํ ์ด๋ธ + ๋งค์นญ๋ ํ ์ด๋ธ)
- RIGHT JOIN ์ ์ค๋ฅธ์ชฝ ํ ์ด๋ธ๋ฐํ (๋งค์นญ๋์ง ์์ ์ค๋ฅธ์ชฝ ํ ์ด๋ธ + ๋งค์นญ๋ ํ ์ด๋ธ)
- FULL OUTER JOIN ์ ์์ชฝ ํ ์ด๋ธ ๋ฐํ (..)
UNION
JOIN ์ ๋ ๊ฐ์ dataset์ ๋๋ํ๊ฒ ์์์ง๋ง, UNION ์ ํ๋์ dateset์ ๋ค๋ฅธ ํ๋์ ์์ (stack)์๋๋ค. UNION ์ ๋ณ๋๋ก ๋ ๊ฐ์ SELECT ๋ฌธ์ ์ฌ์ฉ์ด ๊ฐ๋ฅํ๋ฉฐ, ๋ ๊ฐ์ ๊ฒฐ๊ณผ๋ ํ๋์ ํ ์ด๋ธ์ ํ ๋ฒ์ ์ถ๋ ฅ๋๋ค. ์ฟผ๋ฆฌ์ ์ฒซ ๋ถ๋ถ์ ๊ฒฐ๊ณผ๊ฐ ๋จผ์ ์ถ๋ ฅ๋๊ณ , ๊ทธ ์ดํ์ ๋๋ฒ์งธ ์ฟผ๋ฆฌ์ ๊ฒฐ๊ณผ๊ฐ ์ถ๋ ฅ๋๋ค.
SELECT *
FROM tutorial.crunchbase_investments_part1
UNION
SELECT *
FROM tutorial.crunchbase_investments_part2
UNION ๋ ์ค์ง ๊ณ ์ ํ(distinct) ๊ฐ๋ง ๊ฒฐ๊ณผ๋ก ๋ง๋ ๋ค. ์ฆ, ์ฒซ ๋ฒ์งธ ๋ฌธ์ ๊ฒฐ๊ณผ๊ฐ ํ ์ด๋ธ์ ์ถ๊ฐ(append)๋๊ณ ๋์ ๋ ๋ฒ์งธ ๋ฌธ์ ๊ฒฐ๊ณผ๊ฐ ์ถ๊ฐํ ๋ ๊ฒน์น๋ ํ์ ์ถ๊ฐ๋์ง ์๋๋ค. ๊ณ ์ ํ์ง ์๊ณ ๋ชจ๋ ๋ฌธ์ ๊ฒฐ๊ณผ๋ฅผ ์ถ๊ฐํ๊ณ ์ถ์ ๊ฒฝ์ฐ, UNION ALL ์ ์ฌ์ฉํด์ผ ํ๋ค.
SELECT *
FROM tutorial.crunchbase_investments_part1
UNION ALL
SELECT *
FROM tutorial.crunchbase_investments_part2
SQL์ ๋ฐ์ดํฐ ์ถ๊ฐ(append)์ ์์ด์ ๊น๋ค๋ก์ด ๋ฃฐ์ด ์๋ค
- ์์ชฝ ํ ์ด๋ธ์ ๊ฐ์ ์์ ์ด์ ๊ฐ์ง๊ณ ์์ด์ผ๋ง ํ๋ค.
- ์์ชฝ ํ ์ด๋ธ์ ๊ฐ์ ์์๋ก ๊ฐ์ ๋ฐ์ดํฐ ํ์ ์ ๊ฐ์ง๊ณ ์์ด์ผ ํ๋ค.
์ด์ ์ด๋ฆ์ ๊ฐ์์ผ๋ง ํ๋ ๊ฒ์ ์๋์ง๋ง, UNION ์ ์ฌ์ฉํ ๋๋ ๋๊ฒ ๊ฐ์ ๊ฒ์ด๋ค. ์์ ์์ ์ฒ๋ผ ํ์์ ๊ฐ์ง๋ง ๋ถ๋ฆฌ๋ dataset์ ์ฐ๊ฒฐํ ๋ ์ฃผ๋ก ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ด๋ค.