You& Data_Science & Life

Tableau_Study_1

DashBoard

1. Filtering

  • 대시보드 : 동작 > 동작추가 : 필터
    • [원본 시트] : 필터링 선택하게 될 시트
    • [대상 시트] : 필터링의 결과로 변경될 시트

Vis

Reference

SQL_7_Basic Function

1. 문자 함수

함수 설명
LOWER 모든 문자 소문자 변환
UPPER 모든 문자 대문자 변환
LENGTH 문자 길이
SUBSTR(컬럼, 시작점, 글자수) 문자 값 중 원하는 시작점의 글자수 만큼만 출력
RTRIM 문자열 오른쪽 공백 제거
LTRIM 문자열 왼쪽 공백 제거
TRIM 문자열 양쪽 공백 제거
REPLACE(컬럼, ‘A’, ‘B’) 특정 문자열을 다른 문자열로 대체
COALESCE(컬럼, ‘A’) NULL값을 치환
INITCAP (*only oracle) 첫 글자는 대문자, 나머지는 소문자로 변환
SELECT SUBSTR(seg,2, 3) from card_tran_201311;
-- +------------------+
-- | substr(seg,2, 3) |
-- +------------------+
-- | B                |
-- | B                |
-- | ASS              |
-- | ASS              |
-- | B                |
-- +------------------+


2. 숫자 함수

함수 설명
ROUND 소수점 자릿수를 지정하여 반올림
TRUNC(Oracle)
TRUNCATE (MySQL)
해당 소수점 자리에서 잘라내기
MOD(M,N) M을 N으로 나눈 나머지 반환
ABS 절대값
SIGN 양수는 1, 음수는 -1, 0은 0으로 반환
SQRT 제곱근
PI 지정한 각도의 파이값
SIN 지정한 각도의 SIN값
COS 지정한 각도의 COS값
TAN 지정한 각도의 TAN값
select round(123.456,2);
-- +------------------+
-- | round(123.456,2) |
-- +------------------+
-- |           123.46 |
-- +------------------+

select truncate(123.456,2);
-- +---------------------+
-- | truncate(123.456,2) |
-- +---------------------+
-- |              123.45 |
-- +---------------------+

select mod(123,10);
-- +-------------+
-- | mod(123,10) |
-- +-------------+
-- |           3 |
-- +-------------+

select pi();
-- +----------+
-- | pi()     |
-- +----------+
-- | 3.141593 |



3. 날짜 함수

1) 날짜 연사

함수 설명
ADD_MONTHS (Oracle) 지정한 날짜에 개월 수를 더하거나 뺀 날짜 출력
DATE_ADD (MySQL) 지정한 날짜에 개월 수를 더한 날짜 출력
DATE_SUB (MySQL) 지정한 날짜에 개월 수를 뺀 날짜 출력
DATE_FORMAT (MySQL) 지정한 날짜를 희망하는 포맷으로 변경
DATE_PART (PostgreSql) 지정한 날짜를 희망하는 포맷으로 변경 * isoweeknum 활용!
SELECT DATE_ADD(DLQ_ST, INTERVAL 1 MONTH) from DLQ_PARTY;
-- +------------------------------------+
-- | DATE_ADD(DLQ_ST, INTERVAL 1 MONTH) |
-- +------------------------------------+
-- | 2012-08-30                         |
-- | 2012-10-21                         |

SELECT DATE_ADD(DLQ_ST, INTERVAL 1 DAY) from DLQ_PARTY;
-- +----------------------------------+
-- | DATE_ADD(DLQ_ST, INTERVAL 1 DAY) |
-- +----------------------------------+
-- | 2012-07-31                       |
-- | 2012-09-22                       |

SELECT DATE_ADD(DLQ_ST, INTERVAL -10 DAY) from DLQ_PARTY;
-- +------------------------------------+
-- | DATE_ADD(DLQ_ST, INTERVAL -10 DAY) |
-- +------------------------------------+
-- | 2012-07-20                         |
-- | 2012-09-11                         |


SELECT DATE_SUB(DLQ_ST, INTERVAL 10 DAY) from DLQ_PARTY;
-- +------------------------------------+
-- | DATE_ADD(DLQ_ST, INTERVAL -10 DAY) |
-- +------------------------------------+
-- | 2012-07-20                         |
-- | 2012-09-11                         |


SELECT DATE_ADD(DLQ_ST, INTERVAL 30 SECOND) from DLQ_PARTY;
-- +--------------------------------------+
-- | DATE_ADD(DLQ_ST, INTERVAL 30 SECOND) |
-- +--------------------------------------+
-- | 2012-07-30 00:00:30                  |
-- | 2012-09-21 00:00:30                  |

SELECT DATE_FORMAT(DLQ_ST,'%Y-%m-%d') AS DLQ_SQ from DLQ_PARTY;
-- +------------+
-- | DLQ_SQ     |
-- +------------+
-- | 2012-07-30 |
-- | 2012-09-21 |

-- postgresql
SELECT DATE_PART('week', '2020-10-07') AS ISO_WEEK_NUM;
-- +-------------+
-- | ISO_WEEK_NUM|
-- +-------------+
-- |      41     |

2) 지금 또는 특정 날짜 반환

함수 설명
SYSDATE 현재 시스탬의 날짜 데이터 반환
LAST_DAY 해당 월의 마지막 날짜 반환
MONTH_BETWEEN (Oracle)지정된 월 간의 월 수를 반환
DATEDIFF (MySQL) 지정된 날짜간 차이를 일단위로 반환
TIMESTAMPDIFF (MySQL) 지정된 날짜간 차이를 다양한 단위로 반환
SELECT SYSDATE();
-- +---------------------+
-- | SYSDATE()           |
-- +---------------------+
-- | 2023-06-12 22:05:32 |
-- +---------------------+

SELECT LAST_DAY('2022-01-07');
-- +------------------------+
-- | LAST_DAY('2022-01-07') |
-- +------------------------+
-- | 2022-01-31             |
-- +------------------------+

-- 차이를 일 단위로 표현
SELECT DATEDIFF('1992-01-07', now());
-- +-------------------------------+
-- | DATEDIFF('1992-01-07', now()) |
-- +-------------------------------+
-- |                        -11479 |
-- +-------------------------------+

-- 차이를 분/시/일/주/월/연 단위로 표현
SELECT TIMESTAMPDIFF(MINUTE, '1992-01-07', now());
SELECT TIMESTAMPDIFF(HOUR, '1992-01-07', now());
SELECT TIMESTAMPDIFF(DAY, '1992-01-07', now());
SELECT TIMESTAMPDIFF(WEEK, '1992-01-07', now());
SELECT TIMESTAMPDIFF(MONTH, '1992-01-07', now());
SELECT TIMESTAMPDIFF(YEAR, '1992-01-07', now());
-- +------------------------------------------+
-- | TIMESTAMPDIFF(YEAR, '1992-01-07', now()) |
-- +------------------------------------------+
-- |                                       31 |
-- +------------------------------------------+


+ 연습문제

  • CUST_INFO 테이블
    +---------------+----------+---------+-----------+
    | RESIDENCE_ID  | FIRST_NM | LAST_NM | ANNL_PERF |
    +---------------+----------+---------+-----------+
    | 6705302777666 | MIJA     | HAN     |    -76.77 |
    | 7012012888888 | JINYOUNG | LEE     |    857.61 |
    | 8411011555666 | YOUNGJUN | HA      |    468.54 |
    +---------------+----------+---------+-----------+
    
-- 1) 주민번호 7번째 숫자가 1이면 남자, 2면 여자 일때, GENDER 컬럼을 만들어 남자면 1, 여자면 2로 출력
SELECT FIRST_NM, LAST_NM, SUBSTR(RESIDENCE_ID, 7,1) AS GENDER FROM CUST_INFO;
-- +----------+---------+--------+
-- | FIRST_NM | LAST_NM | GENDER |
-- +----------+---------+--------+
-- | MIJA     | HAN     | 2      |
-- | JINYOUNG | LEE     | 2      |
-- | YOUNGJUN | HA      | 1      |
-- +----------+---------+--------+

-- 2) 고객별 풀네임 생성
SELECT RESIDENCE_ID, CONCAT(LAST_NM,', ',FIRST_NM) AS FULL_NM FROM CUST_INFO;
-- +---------------+---------------+
-- | RESIDENCE_ID  | FULL_NM       |
-- +---------------+---------------+
-- | 6705302777666 | HAN, MIJA     |
-- | 7012012888888 | LEE, JINYOUNG |
-- | 8411011555666 | HA, YOUNGJUN  |
-- +---------------+---------------+

-- 3) 고객별 1년간 수익(ANNL_PERF)을 소숫점 둘째 자리에서 반올림하여, 첫째 짜리 까지 나타내고 별칭은 NEW_ANNL_PERF로 출력
SELECT CONCAT(LAST_NM,', ',FIRST_NM) AS FULL_NM ,
    ROUND(ANNL_PERF, 1) AS NEW_ANNL_PERF
    FROM CUST_INFO;
-- +---------------+------------------+
-- | FULL_NM       | NEW_ANNL_PERF로  |
-- +---------------+------------------+
-- | HAN, MIJA     |            -76.8 |
-- | LEE, JINYOUNG |            857.6 |
-- | SUNG, DAYOUNG |           -890.0 |
-- | SEO, HYEJIN   |             47.4 |
-- | KIM, JIHUN    |            330.1 |
-- | HA, YOUNGJUN  |            468.5 |
-- +---------------+------------------+

Reference

  • 칼퇴족 김대리는 알고 나만 모르는 SQL - 책밥

SQL_6_Text Mining을 활용한 조건 추가

1. Text Mining

와일드 카드 설명
% 숫자 0 또는 문자들을 대체하기 위해 사용
_ 한 개의 단어 대체

1) LIKE

(1) 앞 또는 뒤에 나오는 문자들을 알 수 없는 경우

-- 뒤에 나오는 문자를 알 수 없는 경우
SELECT * FROM table_nm WHERE target_filter_col LIKE '찾고싶은 문자%';

-- 앞에 나오는 문자를 알 수 없는 경우
SELECT * FROM table_nm WHERE target_filter_col LIKE '%찾고싶은 문자';

(2) 앞/뒤에 나오는 문자들을 알 수 없는 경우

: 앞뒤를 고려하지 않고, 원하는 키워드를 포함한 모든 데이터를 필터링 하는 방법

-- 뒤에 나오는 문자를 알 수 없는 경우
SELECT * FROM table_nm WHERE target_filter_col LIKE '%찾고싶은 문자%';

(3) 앞or뒤에 나오는 문자 ‘한 글자’를 알 수 없는 경우

: 앞뒤를 고려하지 않고, 원하는 키워드를 포함한 모든 데이터를 필터링 하는 방법

-- 앞에 나오는 문자 하나를 알 수 없는 경우
SELECT * FROM table_nm WHERE target_filter_col LIKE '_찾고싶은 문자';

-- 뒤에 나오는 문자 하나를 알 수 없는 경우
SELECT * FROM table_nm WHERE target_filter_col LIKE '찾고싶은 문자_';

(4) 시작과 끝 문자만 아는 경우

-- 뒤에 나오는 문자 하나를 알 수 없는 경우
SELECT * FROM table_nm WHERE target_filter_col LIKE '첫 글자%마지막 글자';


2) NOT LIKE

(1) 특정 단어를 원하지 않을 경우

-- 뒤에 나오는 문자 하나를 알 수 없는 경우
SELECT * FROM table_nm WHERE target_filter_col NOT LIKE '%원하지 않는 문자%';


2. 필드 결합하기

* ORCLE과 MYSQL의 코드가 서로 다르니 주의*

1) 여러 열을 하나로 결합하기

-- ORCLE VERSION
SELECT col_nm_1 || col_nm_2  FROM table_nm;

-- MYSQL VERSION
SELECT CONCAT(col_nm_1, col_nm_2)  FROM table_nm;

2) 문자 삽입하기

-- ORCLE VERSION
SELECT col_nm_1 ||'삽입하고 싶은 문자열'||col_nm_2  FROM table_nm;

-- MYSQL VERSION
SELECT CONCAT(col_nm_1, '삽입하고 싶은 문자열',col_nm_2) FROM table_nm;

SELECT PARTY_NM, SEG, CMF, CONCAT(SEG,'_',PARTY_NM,'_',CMF) AS DEP 
FROM PERF_MAST_201312;


3. 공백 제거하기

1) 오른쪽 or 왼쪽 or 양쪽 공백 제거하기

-- 오른쪽 공백 제거 (RTRIM)
SELECT col_nm_1, RTRIM(col_nm_2) FROM table_nm;
-- 왼쪽 공백 제거 (LTRIM)
SELECT col_nm_1, LTRIM(col_nm_2) FROM table_nm;
-- 양쪽 공백 제거 (TRIM)
SELECT col_nm_1, TRIM(col_nm_2) FROM table_nm;

+ 연습문제

  • CUST_PERF 테이블
-- 1) ES라는 문자를 포함하는 도시 중 세달 연속 구매 금액이 300만원이 넘는 고객들만 추출
SELECT * FROM CUST_PERF
WHERE CITY LIKE '%ES%'
AND COALESCE(TOT_AMT_1, 0) > 3000000 
AND COALESCE(TOT_AMT_2, 0) > 3000000 
AND COALESCE(TOT_AMT_3, 0) > 3000000;
-- 2) 고객에게 감사 DM을 발송할 때, 맨 처음 문구가 아래와 같게끔 SQL 문장을 만들어라, 이때, B가 들어 가는 국가는 제외하며, 3개월 연속 구매 실적이 존재하는 고객에게만 전달하라
-- Dear {LEE}, your segment is {PRIORITY} in our company.
SELECT CONCAT('Dear ',NAME,', your segment is ', SEG,' in our company.')
AS DM_DE
FROM CUST_PERF
WHERE CITY NOT LIKE '%B%'
AND COALESCE(TOT_AMT_1, 0) > 0 
AND COALESCE(TOT_AMT_2, 0) > 0 
AND COALESCE(TOT_AMT_3, 0) > 0;

Reference

  • 칼퇴족 김대리는 알고 나만 모르는 SQL - 책밥

SQL_5_logical operator

1. AND, OR 연산자

1) AND

- SELECT * FROM 테이블명 WHERE '조건절_1' AND '조건절_2';

-- 1) 2개의 조건문
SELECT * FROM DLQ_PARTY
WHERE DLQ_DURATION <= 20
    AND DLQ_END IS NOT NULL;


2) OR

- SELECT * FROM 테이블명 WHERE '조건절_1' OR '조건절_2';

SELECT * FROM DLQ_PARTY
WHERE DLQ_ST
BETWEEN '2012-09-01' AND '2013-10-31'
OR DLQ_DURATION >= 20;


3) AND와 OR 우선순위

  • AND 연산자가 OR 연산자보다 선행한다.
  • AND 연산자보다, OR연산자를 먼저 처리하고 싶은 경우, 해당 연산을 괄호로 묶어줘야한다.
-- 1) 괄호를 사용하지 않았을 때, 연산자 우선 순위
SELECT * FROM DLQ_PARTY
WHERE DLQ_DURATION > 15 
AND ACCT_NO < 70000
OR DLQ_ST >= '2013-01-01';
-- 2) 괄호를 사용했을 때, 연산자 우선 순위
SELECT * FROM DLQ_PARTY
WHERE DLQ_DURATION > 15 
AND (ACCT_NO < 70000
OR DLQ_ST >= '2013-01-01');



2. IN, NOT IN

1) IN 연산자

  • - SELECT * FROM 테이블명 WHERE '비교할 컬럼' IN (조건_1, 조건_2);
-- 6,7등급의 사원을 모두 선택하되, 'SS CHANG', 'JW PARK', 'SW HONG'은 반드시 포함
SELECT * FROM EMPLOYEE
WHERE NM IN ('SS CHANG', 'JW PARK', 'SW HONG') 
AND GRADE IN (6, 7);
  • IN 연산자는 OR 연산자보다, 처리속도가 빠르다. 따라서 데이터가 클수록 IN 연산자를 잘 사용하면 좋다.
  • IN 연산자 안에 다른 SELECT 문장을 사용할 수 있다. (이는 하위 쿼리-SUB QUERY에서 자세히 언급)


2) NOT IN 연산자

  • - SELECT * FROM 테이블명 WHERE '비교할 컬럼' NOT IN (조건_1, 조건_2);
-- 6,7등급의 사원을 모두 선택하되, 'SS CHANG', 'JW PARK', 'SW HONG'은 제외
SELECT * FROM EMPLOYEE
WHERE NM NOT IN ('SS CHANG', 'JW PARK', 'SW HONG') 
AND GRADE IN (6, 7);


+ 연습문제

-- 1) 직전 3개월 누적 카드사용금액이 1만원 이하인 고객 추출
SELECT CMF, PARTY_NM, (
  COALESCE(TOT_AMT_1, 0) +
  COALESCE(TOT_AMT_2, 0) +
  COALESCE(TOT_AMT_3, 0)) AS TOT_AMT_1_3 
FROM PERF_MAST_201312
WHERE (
  COALESCE(TOT_AMT_1, 0) +
  COALESCE(TOT_AMT_2, 0) +
  COALESCE(TOT_AMT_3, 0)) < 10000;
-- 2) 직전 3개월 누적 카드사용금액이 1만원 이하인 고객(이탈 고객) 추출
SELECT CMF, PARTY_NM, (
  COALESCE(TOT_AMT_1, 0) +
  COALESCE(TOT_AMT_2, 0) +
  COALESCE(TOT_AMT_3, 0)) AS TOT_AMT 
FROM PERF_MAST_201312
WHERE COALESCE(TOT_AMT_1, 0) < 5000 
AND COALESCE(TOT_AMT_2, 0) < 5000
AND COALESCE(TOT_AMT_3, 0) < 5000;
-- 3) 이탈 고객이면서, 세그먼트가 PB 고객인 고객들 추출
SELECT CMF, PARTY_NM, SEG, (
  COALESCE(TOT_AMT_1, 0) +
  COALESCE(TOT_AMT_2, 0) +
  COALESCE(TOT_AMT_3, 0)) AS TOT_AMT 
FROM PERF_MAST_201312
WHERE COALESCE(TOT_AMT_1, 0) < 5000 
AND COALESCE(TOT_AMT_2, 0) < 5000
AND COALESCE(TOT_AMT_3, 0) < 5000
AND SEG IN ('PB');
-- 4) 직전 3개월동안, 사용금액이 계속 줄어드는 고객중, 
-- 총 사용 금액이 7,000원 이상인 고객 추출
SELECT *, (
  COALESCE(TOT_AMT_1, 0) +
  COALESCE(TOT_AMT_2, 0) +
  COALESCE(TOT_AMT_3, 0)) AS TOT_AMT 
FROM PERF_MAST_201312
WHERE COALESCE(TOT_AMT_1, 0) <= COALESCE(TOT_AMT_2, 0)
AND COALESCE(TOT_AMT_2, 0) <= COALESCE(TOT_AMT_3, 0)
AND (
  COALESCE(TOT_AMT_1, 0) +
  COALESCE(TOT_AMT_2, 0) +
  COALESCE(TOT_AMT_3, 0)
  ) > 7000
;

Reference

  • 칼퇴족 김대리는 알고 나만 모르는 SQL - 책밥

SQL_4_where

WHERE

1. 숫자 & 문자 필터링

` - SELECT * FROM 테이블명 WHERE 비교할 열 이름 = ‘문자’; <br> - SELECT * FROM 테이블명 WHERE 비교할 열 이름 = 숫자;`

-- 1) 문자
SELECT * FROM EMP
WHERE TEAM_NM = '인사팀' 
ORDER BY GRADE;

-- 2) 숫자
SELECT * FROM EMP
WHERE GRADE == 2
ORDER BY GRADE, ID;

+ ORDER BY절은 항상 가장 마지막에 작성해야 한다



2. 비교 산술 연산자

1) 비교 연산자

비교 연산자 설명
A = B A와 B가 같다.
A != B A와 B가 같지 않다.
A < B A가 B 미만이다.
A <= B A가 B 이하이다.
BETWEEN A AND B A이상 B이하 사이값 (A & B 포함)
IS NULL NULL값이 행
IS NOT NULL NULL값이 아닌 행
-- 1) emp 테이블 내에서, 등급이 1~2 사이인 행만 추출
SELECT * FROM EMP 
WHERE GRADE between 1 and 2;

-- 2) DLQ_END값이 NULL값이 아닌 행 찾기
SELECT * FROM DLQ_PARTY 
WHERE DLQ_END IS NOT NULL;

-- 3) PERF 테이블 내에서, SALES_CNT이 20초과 & 30이하인 행만 추출
SELECT * FROM PERF
WHERE SALES_CNT > 20
AND SALES_CNT <=  30
AND VISIT_CNT > 100;

-- 4) PERF 테이블 내에서, 
-- SALES_CNT이 20초과 & 30이하이면서, 방문횟수가 100회 이상인 행만 추출
SELECT * FROM PERF
WHERE SALES_CNT > 20
AND SALES_CNT <=  30
AND VISIT_CNT > 100;


2) 산술연산자 - with SELECT

: SELECT문에서 사용하는 산술연산자는, 주로 새로운 피쳐를 만들때 사용되기에 AS문과 함께 자주 사용됨.

-- 1회 평균 구매 금액 컬럼 생성
SELECT *, SALES_AMT/SALES_CNT AS PER_AMT 
FROM PERF;


3) 산술연산자 - with WHERE

-- SELECT * FROM 테이블
-- WHERE (COL_1 산술연산자 COL_2) 비교연산자 비교할 대상;
-- 1) 새로운 피쳐 생성 하지 않고, 조건절만으로 선택
SELECT * FROM PERF 
WHERE (SALES_CNT/VISIT_CNT * 100) > 30;

-- 2) 새로운 피쳐를 생성하고, 이후 조건절로 선택 
SELECT *,(SALES_CNT/VISIT_CNT * 100) AS SALES_RATE
FROM PERF 
WHERE (SALES_CNT/VISIT_CNT * 100) > 30;


3. NULL값의 처리 하는 함수들

1) COALESCE

COALESCE (EXP_1, EXP_2, ..., EXP_N) <br>
  - EXP_1이 NULL이 아니면 EXP_1을 Return하고, <br> 
  - EXP_1이 NULL이고 EXP_2가 NULL이 아니면 EXP_2를 Return하라 
    - COALESCE ('A', 'B') --> 'A'  <br>
    - COALESCE (NULL, 'B', 'C') --> 'B'  <br>
    - COALESCE (NULL, NULL, 'C') --> 'C'  <br>
    - COALESCE (NULL, 'B', NULL) --> 'B'  <br>

2) ZEROIFNULL(열 이름)

ZEROIFNULL (COL) <br>
  - 해당 열에 NULL이면, 0으로 변경

3) NVL2(열 이름, EXP_1, EXP_2)

COALESCE (EXP_1, EXP_2, ..., EXP_N) <br>
  - 해당 열에 NULL이면, '표현식 2'의 값을 나타내고 <br> 
  - 해당 열에 NULL이 아니면, '표현식 1'의 값을 나타내라


연습문제

-- 1) 사용자별로 총 사용금액
SELECT CMF, PARTY_NM, (
    COALESCE(PIF_AMT, 0) +
    COALESCE(INST_AMT, 0) + 
    COALESCE(OVRS_AMT, 0) + 
    COALESCE(CASH_AMT, 0)
    ) AS TOT_AMT
FROM CARD_TRAN_201311 
ORDER BY TOT_AMT DESC; 

-- 2) PB 고객들을 대상으로, 일시불 사용금액의 10%를 캐시백해줄 때, 사용자별 캐시백 금액 계산
SELECT CMF, PARTY_NM, SEG, PIF_AMT, PIF_AMT*0.1 AS CASH_BACK
FROM CARD_TRAN_201311 
WHERE SEG = 'PB';

Reference

  • 칼퇴족 김대리는 알고 나만 모르는 SQL - 책밥