
- JOIN
두 개 혹은 그 이상의 테이블들을 공통 필드를 가지고 머지하는데 사용. 이는 스타 스키마로 구성된 테이블들로 분산되어 있던 정보를 통합하는데 사용된다. 왼쪽 테이블을 LEFT라고 하고 오른쪽 테이블을 RIGHT라고 할 때 JOIN의 결과는 방식에 상관없이 양쪽의 필드를 모두 가진 새로운 테이블을 만들어내게 된다. 조인의 방식에 따라 다음 두 가지가 달라진다
- 어떤 레코드들이 선택되는지
- 어떤 필드들이 채워지는지
1) 먼저 중복 레코드가 없고 Primary Key의 uniqueness가 보장됨을 체크
2) 조인하는 테이블들간의 관계를 명확하게 정의
3) 어느 테이블을 베이스로 잡을지 (FROM에 사용할지) 결정해야함
SELECT A.*, B.*
FROM raw_data.table1 A
____ JOIN raw_data.table2 B ON A.key1 = B.key1 and A.key2 = B.key2 --INNER, FULL, LEFT, RIGHT, CROSS ...
WHERE A.ts >= '2019-01-01';

여섯 종류의 조인에 대한 실습을 하기에 앞서 실습에 사용될 테이블을 살펴보자

SELECT * FROM raw_data.Vital v
JOIN raw_data.Alert a ON v.vitalID = a.vitalID;

SELECT * FROM raw_data.Vital v
LEFT JOIN raw_data.Alert a ON v.vitalID = a.vitalID;

SELECT * FROM raw_data.Vital v
FULL JOIN raw_data.Alert a ON v.vitalID = a.vitalID;

SELECT * FROM raw_data.Vital v
CROSS JOIN raw_data.Alert a;

SELECT * FROM raw_data.Vital v1
JOIN raw_data.Vital v2 ON v1.vitalID = v2.vitalID;

SELECT
value,
COALESCE(value, 0) --value가 NULL이면 0을 리턴
FROM raw_data.count_test
is NULL을 사용해야 한다. = NULL을 사용할 시 틀린 값을 반환할 수 있다.SELECT COUNT(1)
FROM raw_data.boolean_test
WHERE flag is NULL;
CREATE TABLE adhoc.keeyong_test (
"group" int primary key,
"mailing address" varchar(32)
);


WITH ranked_channels AS (
SELECT
usc.userId,
usc.channel,
st.ts,
ROW_NUMBER() OVER (PARTITION BY usc.userId ORDER BY st.ts) AS row_num_asc,
ROW_NUMBER() OVER (PARTITION BY usc.userId ORDER BY st.ts DESC) AS row_num_desc
FROM
raw_data.user_session_channel usc
JOIN
raw_data.session_timestamp st ON usc.sessionId = st.sessionId
)
SELECT
userId,
MIN(CASE WHEN row_num_asc = 1 THEN channel END) AS first_channel,
MIN(CASE WHEN row_num_desc = 1 THEN channel END) AS last_channel
FROM
ranked_channels
GROUP BY
userId
ORDER BY
userId
LIMIT 15;


SELECT
usc.userId,
SUM(amount) OVER(PARTITION BY usc.userid)
FROM raw_data.user_session_channel AS usc
JOIN raw_data.session_transaction AS revenue ON revenue.sessionId = usc.sessionId
ORDER BY 2 DESC
LIMIT 10;


select * from raw_data.nps
LIMIT 5

SELECT
LEFT(created_at, 7) AS "month",
SUM(CASE WHEN score >= 0 AND score <= 6 THEN 1 ELSE 0 END) AS detractor,
SUM(CASE WHEN score >= 7 AND score <= 8 THEN 1 ELSE 0 END) AS passive,
SUM(CASE WHEN score >= 9 AND score <= 10 THEN 1 ELSE 0 END) AS promoter,
ROUND((promoter - detractor)::FLOAT * 100 / COUNT(*), 2) AS NPS
FROM
raw_data.nps
GROUP BY
1
ORDER BY
