SQL์๊ฐ
SQL ๊ธฐ๋ณธ
๋ค์์ SQL ๋ฌธ์ ์คํํ๋ค๋ฉด ์ธ๋ฏธ์ฝ๋ก ์ผ๋ก ๋ถ๋ฆฌํ๋ค.
ex) sql๋ฌธ1;sql๋ฌธ2
- SQL ์ฃผ์: -- ์ธ๋ผ์ธ ํ์ค์ง๋ฆฌ ์ฃผ์, /--/ ์ฌ๋ฌ ์ค ์ฃผ์
- SQL ํค์๋๋ ๋๋ฌธ์๋ฅผ ์ฌ์ฉํ๋ค๋์ง ํ๋ ๋๋ฆ์ ํฌ๋งทํ
์ด ํ์
ํํ๋ก์ ํธ๋ผ๋ฉด ํ์์ ์ฌ์ฉํ๋ ๊ณตํต ํฌ๋งท์ด ํ์
- ํ
์ด๋ธ/ํ๋ ์ด๋ฆ์ ๋ช
๋ช
๊ท์น ์ ํ๊ธฐ(๋จ์ํ(ex : User) vs. ๋ณต์ํ(Users), snake_case vs. CamelCase)
DDL - ํ
์ด๋ธ ๊ตฌ์กฐ ์ ์ ์ธ์ด
CREATE TABLE
- primary key ์์ฑ์ ์ง์ ํ ์ ์์ผ๋ ๋ฌด์๋จ
primary key uniqueness - big data๋ฐ์ดํฐ์จ์ดํ์ฐ์ค์์๋ ์ง์ผ์ง์ง์์(๋ ์ฝ๋๋ค์ด ์ถ๊ฐ๋ ๋๋ง๋ค ๋ง์์์ ๋ฐ์ดํฐ๋ฅผ ํ์
ํด์ ์ ๋ํฌํ๊ฒ ํด์ค์ผ๋๋๋ฐ ๋๋ฌด ๋ง์์ ์ด๋ ค์)
- CTAS: CREATE TABLE table_name AS SELECT : ํ
์ด๋ธ ์์ฑ๊ณผ ๋์์ ๋ด์ฉ ์ถ๊ฐ ( vs. CREATE TABLE and then INSERT)
- raw_data ์คํค๋ง ์์ user_session_channel ํ
์ด๋ธ ๋ง๋ค๊ธฐ
ex)
CREATE TABLE raw_data.user_session_channel (
userid int,
sessionid varchar(32) primary key,
channel varchar(32)
);
DROP TABLE
- DROP TABLE table_name; ์๋ ํ
์ด๋ธ์ ์ง์ฐ๋ ค๊ณ ํ๋ฉด ์๋ฌ ๋ฐ์
- DROP TABLE IF EXISTS table_name; ํ
์ด๋ธ์ด ์กด์ฌํ ๋ ์ง์
- DELETE FROM ์กฐ๊ฑด์ ๋ง๋ ๋ ์ฝ๋๋ค๋ง ์ง์(ํ
์ด๋ธ ์์ฒด๋ ์กด์ฌ)
ALTER TABLE
- ์๋ก์ด ์ปฌ๋ผ ์ถ๊ฐ: ALTER TABLE ํ
์ด๋ธ์ด๋ฆ ADD COLUMN ํ๋์ด๋ฆ ํ๋ํ์
;
- ๊ธฐ์กด ์ปฌ๋ผ ์ด๋ฆ ๋ณ๊ฒฝ: ALTER TABLE ํ
์ด๋ธ์ด๋ฆ RENAME ํ์ฌํ๋์ด๋ฆ to ์ํ๋์ด๋ฆ;
- ๊ธฐ์กด ์ปฌ๋ผ ์ ๊ฑฐ: ALTER TABLE ํ
์ด๋ธ์ด๋ฆ DROP COLUMN ํ๋์ด๋ฆ;
- ํ
์ด๋ธ ์ด๋ฆ ๋ณ๊ฒฝ: ALTER TABLE ํ์ฌํ
์ด๋ธ์ด๋ฆ RENAME to ์ํ
์ด๋ธ์ด๋ฆ;
DML - ํ
์ด๋ธ ๋ฐ์ดํฐ ์กฐ์ ์ธ์ด
SELECT: ๋ ์ฝ๋ ์ง์ ์ธ์ด
- SELECT FROM: ํ
์ด๋ธ์์ ๋ ์ฝ๋์ ํ๋ ์ฝ์ด์จ๋ค.
- WHERE๋ฅผ ์ฌ์ฉํ์ฌ ๋ ์ฝ๋ ์ ํ ์กฐ๊ฑด ์ง์
- GROUP BY๋ฅผ ํตํด ์ ๋ณด๋ฅผ ๊ทธ๋ฃน ๋ ๋ฒจ์์ ์ถ์ถ
- ORDER BY๋ฅผ ์ฌ์ฉํด ๋ ์ฝ๋ ์์ ๊ฒฐ์
- ๋ค์์ ํ
์ด๋ธ์ JOINํด์ ์ฌ์ฉํ๊ธฐ๋ ํจ
๋ ์ฝ๋ ์์ ์ธ์ด
- INSERT INTO: ํ
์ด๋ธ์ ๋ ์ฝ๋๋ฅผ ์ถ๊ฐํ๋๋ฐ ์ฌ์ฉ
- UPDATE FROM: ํ
์ด๋ธ ๋ ์ฝ๋์ ํ๋ ๊ฐ ์์
- DELETE FROM(vs. TRUNCATE): ํ
์ด๋ธ์์ ๋ ์ฝ๋๋ฅผ ์ญ์
SELECT ์๊ฐ
ํ
์ด๋ธ(๋ค)์์ ๋ ์ฝ๋๋ค(ํน์ ๋ ์ฝ๋ ์)์ ์ฝ์ด์ค๋๋ฐ ์ฌ์ฉํ๋ฉฐ, WHERE๋ฅผ ์ฌ์ฉํด ์กฐ๊ฑด์ ๋ง์กฑํ๋ ๋ ์ฝ๋๋ง ์ฝ์ด์ฌ ์ ์๋ค.
SELECT ํ๋์ด๋ฆ1, ํ๋์ด๋ฆ2, ... -> *๋ฅผ ์ฌ์ฉํ๋ฉด ๋ชจ๋ ํ๋ ์ ํ
FROM ํ
์ด๋ธ์ด๋ฆ
WHERE ์ ํ์กฐ๊ฑด
GROUP BY ํ๋์ด๋ฆ1, ํ๋์ด๋ฆ2, ...
ORDER BY ํ๋์ด๋ฆ [ASC|DESC] -> ํ๋ ์ด๋ฆ ๋์ ์ ์ซ์ ์ฌ์ฉ ๊ฐ๋ฅ
LIMIT N;
ex)
SELECT *
FROM raw_data.user_session_channel;
SELECT *
FROM raw_data.user_session_channel
LIMIT 10;
SELECT DISTINCT channel -> ์ ์ผํ ์ฑ๋ ์ด๋ฆ์ ์๊ณ ์ถ์ ๊ฒฝ์ฐ
FROM raw_data.user_session_channel;
SELECT channel, COUNT(1) -> ์ฑ๋๋ณ ์นด์ดํธ๋ฅผ ํ๊ณ ์ถ์ ๊ฒฝ์ฐ. COUNT ํจ์!!
FROM raw_data.user_session_channel -> SELECT๋ฌธ์ 1๋ฒ ํ๋๋ก GROUP BY ์ํ
GROUP BY 1;
SELECT COUNT(1) -> ์ฑ๋๋ณ๋ก ์ํ ๋ ์ฝ๋ ์๋ฅผ ์นด์ดํธ,ํ
์ด๋ธ์ ๋ชจ๋ ๋ ์ฝ๋ ์ ์นด์ดํธํ๋ ๊ฒฝ์ฐ-> COUNT(*).
FROM raw_data.user_session_channel;
SELECT COUNT(1)
FROM raw_data.user_session_channel
WHERE channel = 'Facebook'; ->channel ์ด๋ฆ์ด Facebook์ธ ๋ ์ฝ๋ ์ ์นด์ดํธ
CASE WHEN
ํ๋๊ฐ์ ๋ณํ์ ์ํด ์ฌ์ฉ ๊ฐ๋ฅํ๋ค.
CASE WHEN ์กฐ๊ฑด THEN ์ฐธ์ผ ๋ ๊ฐ ELSE ๊ฑฐ์ง์ผ ๋ ๊ฐ END ํ๋์ด๋ฆ
์ฌ๋ฌ ์กฐ๊ฑด์ ์ฌ์ฉํ์ฌ ๋ณํํ๋ ๊ฒ๋ ๊ฐ๋ฅํ๋ค.
ex
SELECT
channel,
CASE
WHEN channel in ('Facebook', 'Instagram') THEN 'Social-Media'
WHEN channel in ('Google', 'Naver') THEN 'Search-Engine'
ELSE 'Something-Else'
END channel_type
FROM raw_data.user_session_channel
LIMIT 100;
channel์ด๋ฆ์ผ๋ก ๋ถ๋ฅ๋ฅผ ํ์ฌ channel_type๋ผ๋ ์๋ก์ด ํ๋ ์์ฑ
NULL์ด๋?
- ๊ฐ์ด ์กด์ฌํ์ง ์์์ ๋ํ๋ด๋ ์์. 0 ํน์ ""๊ณผ๋ ๋ค๋ฆ
- ํ๋ ์ง์ ์ ๊ฐ์ด ์๋ ๊ฒฝ์ฐ NULL๋ก ์ง์ ๊ฐ๋ฅ
ํ
์ด๋ธ ์ ์์ ๋ํดํธ ๊ฐ์ผ๋ก๋ ์ง์ ๊ฐ๋ฅ
- ์ด๋ค ํ๋์ ๊ฐ์ด NULL์ธ์ง ์๋์ง ๋น๊ต๋ ํน์ํ ๋ฌธ๋ฒ์ ํ์๋ก ํจ
field1 is NULL: ์ด๋ค ํ๋์ ๊ฐ์ด NULL์ธ์ง ์๋์ง ๋น๊ต
- NULL์ด ์ฌ์น์ฐ์ฐ์ ์ฌ์ฉ๋๋ฉด ๊ทธ ๊ฒฐ๊ณผ๋ ๋ชจ๋ NULL
COUNTํจ์ ์ ๋๋ก ์ดํดํ๊ธฐ

- SELECT COUNT(1) FROM count_test
๋ชจ๋ ๋ ์ฝ๋ ์๋ฅผ ์ธ์ด 7์ ๋ฐํ
- SELECT COUNT(0) FROM count_test
์์ ๊ฐ์ ๊ฒฐ๊ณผ
- SELECT COUNT(NULL) FROM count_test
NULL์ด ์ธ์๋ก ๋ค์ด์ค๋ฉด ์ธ์ง ์์ผ๋ฏ๋ก 0์ ๋ฐํ
- SELECT COUNT(value) FROM count_test
NULL์ด ์๋ value์ ๋ ์ฝ๋ ์๋ฅผ ์ธ์ด 6์ ๋ฐํ
- SELECT COUNT(DISTINCT value) FROM count_test
์ ์ผํ ๊ฐ๋ค(NULL, 1, 0, 4, 3) ์ค NULL์ด ์๋ ๊ฐ๋ง ์ธ์ด 4๋ฅผ ๋ฐํ
WHERE
- IN and NOT IN
- WHERE channel in ('Google', 'Youtube')
- WHERE channel = 'Google' OR channel = 'Youtube'
- LIKE and ILIKE
- LIKE: ๋์๋ฌธ์๋ฅผ ๊ตฌ๋ถ
- ILIKE: ๋์๋ฌธ์๋ฅผ ๊ตฌ๋ถํ์ง ์์
- WHERE channel LIKE 'G%' ->'G*(์ฑ๋๋ช
์ด G๋ก ์์ํ๋ ์ฑ๋)
- WHERE channel LIKE '%o%' ->o(์ฑ๋๋ช
์ o๊ฐ ๋ค์ด์๋ ์ฑ๋)
- NOT LIKE or NOT ILIKE
- BETWEEN
- ๋ ์ง์ฌ์ด์ ๋ค์ด๊ฐ๋ฉด ๋งค์นญ
ex)
SELECT COUNT(1)
FROM raw_data.user_session_channel
WHERE channel in ('Google','Facebook');
SELECT DISTINCT channel
FROM raw_data.user_session_channel
WHERE channel ILIKE '%o%';
์ฑ๋๋ช
์ o๊ฐ ๋ค์ด์๋ ์ฑ๋์ ๊ตฌ๋ถ๋๋ ์ฑ๋๋ง ์ถ๋ ฅ
STRING Functions
- LEFT(str, N): ์ผ์ชฝ๋ถํฐ N๊ฐ ๋ฌธ์์ด๋ง ์ถ์ถ
- REPLACE(str, exp1, exp2): ์ฃผ์ด์ง ๋ฌธ์์ด์์ exp1์ exp2๋ก ๋์ฒด
- UPPER(str) : ๋๋ฌธ์๋ก ๋ณํ
- LOWER(str) : ์๋ฌธ์๋ก ๋ณํ
- LEN(str) : ๋ฌธ์์ด์ ๊ธธ์ด ์ถ์ถ
- LPAD, RPAD: ๋ฌธ์์ด์ ์ผ์ชฝ/์ค๋ฅธ์ชฝ์ ๋ฌธ์ padding
- SUBSTRING: ๋ฒ์๋ฅผ ์ง์ ํ์ฌ ๋ฌธ์์ด ์ถ์ถ
ex)
SELECT
LEN(channel),
UPPER(channel),
LOWER(channel),
LEFT(channel, 4)
FROM raw_data.user_session_channel
LIMIT 100;
ORDER BY
- ๋ํดํธ๊ฐ์ ์ค๋ฆ์ฐจ์์ผ๋ก ์ ๋ ฌํ๋ค.
- ๋ด๋ฆผ์ฐจ์ ์ ๋ ฌ์ ํ๊ณ ์ถ๋ค๋ฉด "DESC" ๋ช
์
- ์ฌ๋ฌ ๊ฐ ์ปฌ๋ผ์ ๊ธฐ์ค์ผ๋ก ์ ๋ ฌํ ์ ์์ ORDER BY 1 DESC, 2, 3
- NULL๊ฐ์ ์์
NULL๊ฐ๋ค์ ์ค๋ฆ์ฐจ์์ผ ๊ฒฝ์ฐ ๋ง์ง๋ง์, ๋ด๋ฆผ์ฐจ์์ผ ๊ฒฝ์ฐ ์ฒ์์ ์์นํจ
์ด๋ฅผ ๋ฐ๊พธ๋ ค๋ฉด NULLS FIRST ํน์ NULLS LAST ์ฌ์ฉ
Type Casting
1/2์ ๊ฒฐ๊ณผ๋ 0์ด๋จ. ์ ์๊ฐ์ ์ฐ์ฐ์ ์ ์๊ฐ ๋์ด์ผ ํ๊ธฐ ๋๋ฌธ์ด๋ค.
๋ฐ๋ผ์ ๋ถ์๋ ๋ถ๋ชจ์ค์ ํ๋๋ฅผ float์ผ๋ก ์บ์คํ
ํด์ผ 0.5๊ฐ ๋์ด
์บ์คํ
ํ๋ ๋ฐฉ๋ฒ์ ๋๊ฐ์ง๊ฐ ์๋ค.
- ์คํผ๋ ์ดํฐ๋ฅผ ์ฌ์ฉ
category::float
- castํจ์๋ฅผ ์ฌ์ฉ
cast(category as float)
Pandas๋ ์ฐ๋ํ๋ ๋ฒ
result = %sql SELECT * FROM raw_data.user_session_channel
์ด ํ ํ๋ค์ค ๋ฌธ๋ฒ์ ์ด์ฉํ์ฌ ์ฌ์ฉ ๊ฐ๋ฅ
df = result.DataFrame()
df.groupby(["channel"]).size()
df.groupby(["channel"])["sessionid"].count()
๋!