SQL 조인은 두 개 혹은 그 이상의 테이블들을 공통 필드를 가지고 머지하는데
사용된다. 이는 스타 스키마로 구성된 테이블들로 분산되어 있던 정보를 통합하는데
사용된다.
왼쪽 테이블을 LEFT라고 하고 오른쪽 테이블을 RIGHT이라고 하자. JOIN의 결과는 방식에 상관없이 양쪽의 필드를 모두 가진 새로운 테이블을 만들어내게 된다.
조인의 방식에 따라 다음 두 가지가 달라진다:

Source: https://theartofpostgresql.com/blog/2019-09-sql-joins/
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 (대부분 INNER와 LEFT 사용)
WHERE A.ts >= '2019-01-01';
먼저 중복 레코드가 없고 Primary Key의 uniqueness가 보장됨을 체크
조인하는 테이블들간의 관계를 명확하게 정의

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
COUNT(CASE WHEN flag = True THEN 1 END) true_cnt1,
COUNT(CASE WHEN flag is True THEN 1 END) true_cnt2,
COUNT(CASE WHEN flag is not False THEN 1 END) not_false_cnt
FROM raw_data.boolean_test;
SELECT COUNT(1)
FROM raw_data.boolean_test
WHERE flag is NULL;
SELECT COUNT(1)
FROM raw_data.boolean_test
WHERE flag = NULL;
SELECT LEFT(ts, 7) "month",
usc.channel,
COUNT(DISTINCT userid) uniqueUsers
FROM raw_data.user_session_channel usc
JOIN raw_data.session_timestamp t ON t.sessionid = usc.sessionid
GROUP BY 1, 2
ORDER BY 1, 2;
raw_data.user_session_channel
raw_data.session_timestamp
raw_data.session_transaction
SELECT LEFT(ts, 7) "month",
usc.channel,
COUNT(DISTINCT userid) uniqueUsers
FROM raw_data.user_session_channel usc
JOIN raw_data.session_timestamp t ON t.sessionid = usc.sessionid
LEFT JOIN raw_data.session_transaction st ON st.sessionid = usc.sessionid
GROUP BY 1, 2
ORDER BY 1, 2;
SELECT LEFT(ts, 7) "month",
usc.channel,
COUNT(DISTINCT userid) uniqueUsers,
COUNT(DISTINCT CASE WHEN amount > 0 THEN usc.userid END) paidUsers,
FROM raw_data.user_session_channel usc
JOIN raw_data.session_timestamp t ON t.sessionid = usc.sessionid
LEFT JOIN raw_data.session_transaction st ON st.sessionid = usc.sessionid
GROUP BY 1, 2
ORDER BY 1, 2;
SELECT LEFT(ts, 7) "month", -- "year month"
channel,
COUNT(DISTINCT usc.userid) uniqueUsers,
COUNT(DISTINCT CASE WHEN amount > 0 THEN usc.userid END) paidUsers,
ROUND(paidUsers::float*100/NULLIF(uniqueUsers, 0),2) conversionRate,
SUM(amount) grossRevenue,
SUM(CASE WHEN refunded is False THEN amount END) netRevenue
FROM raw_data.user_session_channel usc
LEFT JOIN raw_data.session_timestamp t ON t.sessionid = usc.sessionid
LEFT JOIN raw_data.session_transaction st ON st.sessionid = usc.sessionid
GROUP BY 1, 2
ORDER BY 1, 2;
SELECT
value,
COALESCE(value, 0) -- value가 NULL이면 0을 리턴
FROM raw_data.count_test;
CREATE TABLE keeyong.test (
group int primary key,
'mailing address' varchar(32)
);
DROP TABLE IF EXISTS adhoc.keeyong_monthly_channel_summary;
CREATE TABLE adhoc.keeyong_monthly_channel_summary AS
SELECT LEFT(ts, 7) "month",
channel,
COUNT(DISTINCT usc.userid) uniqueUsers,
COUNT(DISTINCT CASE WHEN amount > 0 THEN usc.userid END) paidUsers,
ROUND(paidUsers::float*100/NULLIF(uniqueUsers, 0),2) conversionRate,
SUM(amount) grossRevenue,
SUM(CASE WHEN refunded is False THEN amount END) netRevenue
FROM raw_data.user_session_channel usc
LEFT JOIN raw_data.session_timestamp t ON t.sessionid = usc.sessionid
LEFT JOIN raw_data.session_transaction st ON st.sessionid = usc.sessionid
GROUP BY 1, 2;