SQL을 이용한 데이터 분석
AWS 콘솔을 통해 Redshift를 론치해보자.
Redshift 클릭/검색해서 Redshift 콘솔로 이동한다.
create cluster
cluster configuration 클러스터 구성
database configuration 데이터베이스 구성
cluster permissions
additional configuration 외부에서 엑세스 가능하게
end point 가지고 엑세스 한다.
앞으로 실습에서 사용할 테이블들이다.
실습의 주제가 마케팅에 관련된 것이기 때문에, 이해하는데 필요한 사전 지식을 알아보자.
사용자 ID: 보통 웹서비스에서 등록된 사용자마다 부여하는 유일한 ID이다.
세션 ID: 세션마다 부여되는 ID이다.
정리하자면 세션이 생길 때 기록하는 정보는 다음과 같다.
이 정보를 기반으로 다양한 데이터 분석과 지표 설정이 가능하다.
총 3개의 세션(파란 배경)을 갖는 예제 테이블을 살펴보자.
두 개의 테이블이 있다.
먼저 다수의 SQL 문을 실행한다면 세미콜론으로 분리해야 한다.
SQL 주석
SQL 키워드는 대문자를 사용한다던지 하는 나름대로의 포맷팅이 필요하다.
테이블/필드이름의 명명규칙을 정하는 것이 중요
데이터를 생성, 수정, 삭제하는 등의 데이터의 전체적인 골격을 결정하는 역할을 한다.
CREATE TABLE
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
DELETE FROM
은 조건에 맞는 레코드들을 지운다. (테이블 자체는 존재)ALTER TABLE
ALTER TABLE 테이블이름 ADD COLUMN 필드이름 필드타입;
ALTER TABLE 테이블이등 RENAME 현재필드이름 to 새필드이름
ALTER TABLE 테이블이름 DROP COLUMN 필드이름;
ALTER TABLE 현재테이블이름 RENAME to 새테이블이름;
정의된 데이터베이스에 입력된 레코드를 조회하거나 수정, 삭제하는 등의 역할을 한다.
SELECT
SELECT FROM
: 테이블에서 레코드와 필드를 읽어오는데 사용된다.WHERE
를 사용해서 레코드 선택 조건을 지정한다.GROUP BY
를 통해 정보를 그룹 레벨에서 뽑는데 사용하기도 한다.GROUP BY
를 필요로 한다.레코드 수정 언어:
INSERT INTO
: 테이블에 레코드를 추가하는데 사용UPDATE FROM
: 테이블 레코드의 필드 값 수정DELETE FROM
: 테이블에서 레코드를 삭제TRUNCATE
(transaction x)처음 쓰는 데이터로 일을 하기 전에 꼭 염두해야 할 부분이다.
현업에서 깨끗한 데이터란 존재하지 않는다.
데이터 일을 한다면 항상 데이터의 품질을 의심하고 체크하는 버릇이 필요하다.
위의 체크는 코딩의 unit test 형태로 만들어 매번 쉽게 체크해볼 수 있다.
주피터 SQL 엔진 설정
%load_ext sql
버전 충돌 막기 위해 다운그레이드
!pip install ipython-sql==0.4.1
!pip install SQLAlchemy==1.4.49
RedShift의 데이터베이스와 연결
%sql postgresql://username:password@hostname/dbname
sql 코드 입력할 때 이런 식으로 위에 선언하고 한칸 띄우고 시작해야한다.
%%sql
SELECT ...
SELECT 필드이름1, 필드이름2,...
FROM 테이블이름
WHERE 선택조건
GROUP BY 필드이름1, 필드이름2, ...
ORDER BY 필드이름 [ASC|DESC] -- 필드 이름 대신에 숫자 사용 가능
- 오름차순|내림차순
LIMIT N;
SELECT 예시
SELECT * -- 모든 필드 읽어오기
FROM raw_data.user_session_channel;
SELECT DISTINCT channel -- 유일한 채널 이름을 알고싶은 경우
FROM raw_data.user_session_channel;
SELECT channel, COUNT(1) -- 채널별 카운트를 하고 싶은 경우 COUNT 함수
FROM raw_data.user_session_channel
GROUP BY 1; -- channel
SELECT COUNT(1) -- 테이블의 모든 레코드 수 카운트. COUNT(*). 하나의 레코드
FROM raw_data.user_session_channel;
SELECT COUNT(1)
FROM FROM raw_data.user_session_channel
WHERE channel='Facebook'; -- channel 이름이 Facebook인 경우만 고려해서 레코드 수 카운트
필드 값의 변환을 위해 사용 가능하다.
CASE
WHEN 조건1 THEN 값1
WHEN 조건2 THEN 값2
ELSE 값3
END 필드이름
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;
field1 is NULL
혹은 field1 is not NULL
COUNT 함수를 제대로 이해하기 위해 레코드가 7개인 테이블을 생각해 보자.
IN
LIKE
and ILIKE
LIKE
, 대소문자 구별하지 않으면 ILIKE
쓰면 된다.BETWEEN
위의 오퍼레이터들은 CASE WHEN 사이에서도 사용가능하다.
LEFT(str, N)
REPLACE(str, exp1, exp2)
UPPER(str)
LOWER(str)
LEN(str)
LPAD, RPAD
SUBSTRING
%%sql
SELECT
LEN(channel),
UPPER(channel),
LOWER(channel),
LEFT(channel, 4)
FROM raw_data.user_session_channel
LIMIT 100;
ORDER BY 1 ASC
ORDER BY 1 DESC
ORDER BY 1 DESC, 2, 3
NULLS FIRST
혹은 NULLS LAST
를 사용하면 된다.숫자 계산할때 많이 쓰인다.
프로그래밍에서 1/2의 결과는?
:: 오퍼레이터 사용
category::float
cast 함수를 사용
cast(category as float)
%%sql
SELECT 1/2, 1/2::float;
result = %sql SELECT * FROM raw_data.user_session_channel
df = result.DataFrame()