2022. 2. 6. 05:53ㆍ독학으로 취업 문 뿌수기/SQL
1-1. SQL과 관계형 데이터베이스
1-2. MySQL과 Workbench
1-3 Workbench 살펴보기

- /* */ - 주석처리
- Ctrl + T - 새로운 쿼리창 열기
- Ctrl + Enter - 쿼리 실행 (해당 명령어 줄을 선택한 후)
- Ctrl + S - 쿼리 저장
- 세미클론(;) - 명령어 마침표
- CREATE DATABASE 데이터베이스명; - 데이터 베이스 생성할 때 사용하는 명령어
- USE 데이터베이스명; - 해당 데이터베이스 사용
- DROP DATABASE 데이터베이스명; - 데이터베이스 삭제
2. SQL 명령어
2-1. 데이터 정의어(DDL): 테이블을 생성, 변경, 삭제할 때 사용하는 명령어

- 테이블은 각 열마다 반드시 1가지 데이터 타입(숫자형, 문자형, 날짜형, 0과 1(숫자 논리형))으로 정의되어야 한다.
- 테이블은 각 열마다 제약조건(PK, NOT NULL)을 정의할 수 있다.
- PK = 중복되어 나타날 수 없는 단일 값 + NOT NULL(빈 값NULL 허용하지 않음)
CREATE TABLE 회원테이블 (
회원번호 INT PRIMARY KEY,
이름 VARCHAR(20),
가입일자 DATE NOT NULL,
수신동의 BIT
);
- CREATE TABLE 테이블명 - 테이블 생성
- ALTER TABLE 테이블명 ADD 열이름 VARCHAR(2); - 테이블 열 추가
- ALTER TABLE 테이블명 MODIFY 열이름 VARCHAR(20); - 열 데이터 타입 변경
- ALTER TABLE 테이블명 CHANGE 열이름 변경하고자 하는 열이름 VARCHAR(2); - 열 이름 변경
- ALTER TABLE 테이블명 RENAME 변경하고자 하는 테이블명; - 테이블 이름 변경
- DROP TABLE 테이블명; - 테이블 삭제
CREATE DATABASE 데이터베이스 생성 >> USE 데이터베이스 사용 >> CREATE TABLE 테이블 생성 >> INSERT 데이터 삽입
2-2. 데이터 조작어(DML): 데이터를 삽입, 조회, 수정, 삭제할 때 사용하는 명령어
데이터를 삽입하기 전 테이블을 미리 생성해야 한다.
- INSERT INTO 테이블명 VALUES (1001, '홍길동', '2020-01-02', 1); - 테이블에 (테이블 열 순서대로)데이터 삽입
- 데이터가 문자형과 날짜형인 것은 '따옴표'로 표시해야 한다.
- SELECT * FROM 테이블명; - 해당 테이블의 모든 열 조회
- SELECT 열이름 FROM 테이블명; - 특정 열 조회
- SELECT 열이름1, 열이름2 AS 변경할 열이름 FROM 테이블명; - 특정 열 이름 변경하여 조회(열이름2가 변경된다)
- UPDATE 테이블명 SET 데이터가 수정될 열이름 = 0(조건설정); - (해당 열) 모든 데이터 수정
- UPDATE 테이블명 SET 수신동의(열이름) = 1(조건설정) WHERE 이름(열이름) = '홍길동'; - 특정 조건 데이터 수정(이름이 홍길동인 행만 수신동의를 1로 변경한다)
- DELETE FROM 테이블명 - 테이블 내 모든 데이터 삭제
- DELETE FROM 테이블명 WHERE 이름(열이름) = '홍길동'; - 특정 데이터 삭제(이름이 홍길동인 행의 데이터 모두 삭제)
2-3. 데이터 제어어(DCL): 데이터 접근 권한 부여 및 제거할 때 사용하는 명령어
사용자를 추가하기 위해 먼저 MYSQL 데이터베이스를 사용해야 한다.
- USE MYSQL - MYSQL 데이터베이스 사용
- SELECT * FROM USER; - 사용자 확인
- CREATE USER 'TEST'(아이디)@LOCALHOST(로컬접속가능) IDENTIFIED BY 'TEST'(비밀번호); - 사용자 아이디와 비밀번호 생성
- SET PASSWORD FOR 'TEST'@LOCALHOST = '1234'; - 사용자 비밀번호 변경
- 권한: CREATE, ALTER, DROP, INSERT, DELETE, UPDATE, SELECT, 등
- GRANT ALL ON Practice.회원테이블 TO 'TEST'@LOCALHOST; - 모든 권한 부여
- REVOKE ALL ON Practice.회원테이블 FROM 'TEST'@LOCALHOST; - 모든 권한 제거
- GRANT SELECT, DELETE(권한) ON PRACTICE(데이터베이스명).회원테이블(테이블명) TO 'TEST'(권한을 부여할 아이디)@LOCALHOST; - 특정 권한 부여
- REVOKE DELETE(권한) ON PRACTICE.회원테이블 FROM 'TEST'@LOCALHOST; - 특정 권한 제거
- DROP USER 'TEST'@LOCALHOST; - 사용자 삭제
2-4. 트랜젝션 제어어(TCL): 데이터 조작어(DML) 명령어 실행, 취소, 임시저장할 때 사용하는 명령어
트랜젝션 시작 BIGIN >> 데이터 삽입 INSERT (+수정, 삭제) >> 실행 COMMIT or 취소 ROLLBACK
- 트랜젝션(Transaction)은 분할할 수 없는 최소 단위이며 논리적인 작업 단위
- 실행(COMMIT): 모든 작업을 최종 실행 (트랜젝션을 빠져나옴) COMMIT;
- 취소(ROLLBACK): 모든 작업을 되돌림 ROLLBACK;
- BEGIN; - 트랜젝션 시작
- 임시저장(SAVEPOINT): ROLLBACK 저장점을 지정하는 명령어
- SAVEPOINT S1(임시저장명);
- ROLLBACK TO S2; - 원하는 지점으로 되돌림
3-1. 데이터 조회(SELECT): 데이터 조작어(DML)이며, 데이터 분석에서 가장 많이 사용되는 명령어
- 여러 절들과 함께 사용되어, 분석에 필요한 데이터 조회
- 절: FROM, WHERE, GROUP BY, HAVING, ORDER BY
- FROM절: 테이블 확인
- WHERE절: FROM절 테이블을 특정 조건을 필터링
- GROUP BY절: (여러)열 별로 그룹화 (기존 테이블이 새로운 테이블로 변환됨) (WHERE절 아래에 적어야 함)
- HAVING절: 그룹화된 새로운 테이블을 특정 조건으로 필터링 (GROUP BY와 함께 쓰이며 그 아래에 적어야 함)
- SELECT절: 열 선택
- ORDER BY절: 열 정렬 (맨 하단에 작성해야 함)
- .CSV 테이블 데이터를 들고 오기 위해 해당 데이터베이스 우클릭 'Table Date Import' 선택 후 테이블명과 데이터 타입(숫자, 문자, 날짜형)을 설정한다.
<성별이 남성 조건으로 필터링하여 / 거주지역별로 구매횟수 집계 / 구매횟수 100회 미만 조건으로 필터링 / 구매횟수가 낮은 순으로>
SELECT ADDR
,COUNT(MEM_NO) AS 회원수
FROM CUSTOMER
WHERE GENDER = 'MAN'
GROUP
BY ADDR
HAVING COUNT(MEM_NO) < 100
ORDER BY COUNT(MEM_NO) DESC;
- GROUP BY 뒤 그룹화할 열이름을 적고 SELECT 뒤에도 똑같이 적는다. (지역별-ADDR-로 데이터가 조회되어야 하기에) (집계함수와 같이 사용됨)
- 지역별로 회원수를 구하기 = 행 개수 구하기
- 집계함수 COUNT(MEM_NO) = 해당 열에 대한 행들의 개수를 구함 (AS로 COUNT 함수에 대한 열이름을 지정해줌)
- DESC : 내림차순 / ASC : 오름차순
<거주지역을 서울, 인천 조건으로 필터링 / 거주지역 및 성별로 회원수 집계>
SELECT ADDR
,GENDER
,COUNT(MEM_NO) AS 회원수
FROM CUSTOMER
WHERE ADDR IN ('SEOUL', 'INCHEON')
GROUP BY ADDR, GENDER;
- IN : 특수 연산자 / IN (List) / 리스트 값만
3-2. 데이터 결합(JOIN)
- 테이블 결합은 두 테이블 관계를 활용하여 테이블을 결합하는 명령어
- 관계: 1:1, 1:N, N:N
- ERM(Entity-Relationship Modelling): 개체-관계 모델링이며, 관계형 데이터베이스에 테이블을 모델링할 때 사용
- 개체(Entity): 하나 이상의 속성(=열)으로 구성된 객체(=테이블)
- 1명의 회원이 여러(N)번 주문하고 = 1:N / 1개의 상품은 여러(N)번 주문된다. = N:1

- ERD(Entity-Relationship Diagram): 개체 간의 관계를 도표로 표현할 때 사용

- INNER JOIN: 두 테이블의 공통 값이 매칭되는 데이터만 결합 (FROM절부터 ON절까지 하나의 테이블로 여기면 됨)
SELECT *
FROM CUSTOMER AS A
INNER
JOIN SALES AS B
ON A.MEM_NO(=회원테이블의 회원번호) = B.MEM_NO(=주문테이블의 회원번호) (결합조건)
WHERE A.MEM_NO = '1000970'; >>> 해당 회원번호의 고객이 주문을 N번한 것을 확인할 수 있다. (1:N 관계)
- LEFT JOIN: 두 테이블의 공통 값이 매칭되는 데이터만 결합 + 왼쪽 테이블의 매칭되는 않는 데이터는 NULL 처리
- 회원(CUSTOMER)정보는 있는데 주문정보가 없으면 해당 회원의 주문정보는 NULL로 처리 (=회원가입만하고 주문은 하지 않는 회원)
- RIGHT JOIN: 두 테이블의 공통 값이 매칭되는 데이터만 결합 + 오른쪽 테이블의 매칭되는 않는 데이터는 NULL
- 회원정보는 없는데 주문(SALES)정보는 있으면 해당 주문의 회원정보는 NULL로 처리 (=비회원이 주문)
- IS NULL: 비교 연산자 / NULL인 값만 필터링
SELECT *
FROM CUSTOMER AS A
RIGHT
JOIN SALES AS B
ON A.MEM_NO = B.MEM_NO
WHERE A.MEM_NO IS NULL;
임시테이블 생성
CREATE TEMPORARY TABLE CUSTOMER_SALES_INNER_JOIN (임시테이블명)
SELECT A.* >>> CUSTOMER 테이블의 모든 열
,B.ORDER_NO >>> SALES 테이블의 주문번호 열
FROM CUSTOMER AS A
INNER
JOIN SALES AS B
ON A.MEM_NO = B.MEM_NO;
- 임시테이블(TEMPORARY TABLE)은 서버 연결 종료시 자동으로 삭제된다.
- 임시테이블도 중복되는 절을 가져올 수 없으므로 고객테이블은 모든 열을 가져오되 판매테이블은 회원정보를 제외한 열만 가져와야 한다.
3개 이상 테이블 결합
SELECT *
FROM SALES AS A >>> 주문테이블이 기준
LEFT
JOIN CUSTOMER AS B
ON A.MEM_NO = B.MEM_NO >>> 고객테이블을 회원번호 기준으로 결합
LEFT
JOIN PRODUCT AS C
ON A.PRODUCT_CODE = C.PRODUCT_CODE; >>> 제품테이블을 상품코드 기준으로 결합
3-3. 서브 쿼리(SUB QUERY): SELECT문 안에 또 다른 SELECT문이 있는 명령어
SELECT절 서브쿼리
SELECT *
,(SELECT GENDER FROM CUSTOMER WHERE A.MEM_NO = MEM_NO(고객테이블의 회원번호)) AS GENDER
FROM SALES AS A;
- JOIN을 사용하지 않고 다른 테이블의 정보를 가져올 수 있다. BUT 처리속도가 느림.
<위와 동일한 값 출력>
SELECT A.*
,B.GENDER
FROM SALES AS A
LEFT
JOIN CUSTOMER AS B
ON A.MEM_NO = B.MEM_NO;
FORM절 서브쿼리
>>> 가장 많이 사용됨
SELECT *
FROM (
SELECT MEM_NO
,COUNT(ORDER_NO) AS 주문횟수
FROM SALES
GROUP
BY MEM_NO
)AS A;
- FROM절 뒤에는 테이블명이 와야 하기에 그 자리에 GROUP BY절로 새로 생성된 테이블이 옴.
- 열 및 테이블명(=회원별 주문횟수) 지정해줘야 한다.
WHERE절 서브쿼리
<2019년도에 가입한 회원의 주문 횟수>
SELECT COUNT(ORDER_NO) AS 주문횟수
FROM SALES
WHERE MEM_NO IN (SELECT MEM_NO FROM CUSTOMER WHERE YEAR(JOIN_DATE) = 2019);
- YEAR: 날짜형 함수 / 연도 변환
SELECT COUNT(A.ORDER_NO) AS 주문횟수
FROM SALES AS A
INNER
JOIN CUSTOMER AS B
ON A.MEM_NO = B.MEM_NO
WHERE YEAR(B.JOIN_DATE) = 2019;
CREATE TEMPORARY TABLE SALES_SUB_QUERY
SELECT A.구매횟수
,B.*
FROM (
SELECT MEM_NO
,COUNT(ORDER_NO) AS 구매횟수
FROM SALES
GROUP
BY MEM_NO
)AS A
INNER
JOIN CUSTOMER AS B
ON A.MEM_NO = B.MEM_NO;
<성별이 남성 조건으로 필터링하여 / 거주지역별로 구매횟수 집계 / 구매횟수 100회 미만 조건으로 필터링 / 구매횟수가 낮은 순으로 정렬>
SELECT ADDR
,SUM(구매횟수) AS 구매횟수
FROM SALES_SUB_QUERY
WHERE GENDER = 'MAN'
GROUP
BY ADDR
HAVING SUM(구매횟수) < 100
ORDER
BY SUM(구매횟수) ASC;
4-1. 연산자

- WHERE ADDR LIKE 'D%'; = ADDR열의 D로 시작하는 행들만
- WHERE ADDR LIKE '%N'; = ADDR열의 N으로 끝나는 행들만
- WHERE ADDR LIKE '%EO%'; = ADDR열의 EO가 포함된 행들만
집합 연산자 예시
CREATE TEMPORARY TABLE SALES_2019
SELECT *
FROM SALES
WHERE YEAR(ORDER_DATE) = '2019';
/* 1235행 */
SELECT *
FROM SALES_2019;
/* 3115행 */
SELECT *
FROM SALES;
/* UNION : 2개 이상 테이블 중복된 행 제거 하여 집합(* 열 개수와 데이터 타입 일치) */
SELECT *
FROM SALES_2019
UNION
SELECT *
FROM SALES;
/* UNION ALL: 2개 이상 테이블 중복된 행 제거 없이 집합(* 열 개수와 데이터 타입 일치) */
SELECT *
FROM SALES_2019
UNION ALL
SELECT *
FROM SALES;
4-2. 함수: 특정 규칙에 의해 새로운 결과값으로 반환하는 명령어

- 단일행 함수: 모든 행에 대해 각각 함수가 적용되어 반환한다. / 함수들을 중첩해서 사용할 수 있다.

- DATE_FORMAT('2022-12-31', '%M-%D-%Y'); = 월일년을 대문자로 적용할 경우 'December-31st-2022'형식으로 출력
- 복수행 함수: 여러 행들이 하나의 결과값으로 반환한다. / 주로 GROUP BY절과 함께 사용된다.

- 윈도우 함수: 행과 행간의 관계를 정의하여 결과 값을 반환한다.
- ORDER BY: 행과 행간의 순서를 정한다
- PARTITION BY: 그룹화

SELECT MEM_NO
,ORDER_DATE
,ROW_NUMBER() OVER (PARTITION BY MEM_NO ORDER BY ORDER_DATE ASC) AS 고유한_순위_반환
,RANK() OVER (PARTITION BY MEM_NO ORDER BY ORDER_DATE ASC) AS 동일한_순위_반환
,DENSE_RANK() OVER (PARTITION BY MEM_NO ORDER BY ORDER_DATE ASC) AS 동일한_순위_반환_하나의등수
FROM SALES;
4-3. VIEW 및 PROCEDURE
- VIEW: 하나 이상의 테이블들을 활용하여, 사용자가 정의한 가상 테이블
- JOIN 사용을 최소화하여, 편의성을 최대화한다.
<VIEW 생성>
CREATE VIEW SALES_PRODUCT AS
SELECT A.*
,A.SALES_QTY * B.PRICE AS 결제금액
FROM SALES AS A
LEFT
JOIN PRODUCT AS B
ON A.PRODUCT_CODE = B.PRODUCT_CODE;
<VIEW 수정>
ALTER VIEW SALES_PRODUCT AS
SELECT A.*
,A.SALES_QTY * B.PRICE * 1.1 AS 결제금액_수수료포함
FROM SALES AS A
LEFT
JOIN PRODUCT AS B
ON A.PRODUCT_CODE = B.PRODUCT_CODE;
<VIEW 삭제>
DROP VIEW SALES_PRODUCT;
- PROCEDURE: 매개변수(IN, OUT, INOUT)를 활용해 사용자가 정의한 작업을 저장

IN 매개변수
DELIMITER //
CREATE PROCEDURE CST_GEN_ADDR_IN( IN INPUT_A VARCHAR(20), INPUT_B VARCHAR(20) )
BEGIN
SELECT *
FROM CUSTOMER
WHERE GENDER = INPUT_A
AND ADDR = INPUT_B; >>> IN 매개변수의 조건이 WHERE(프로슈저)로 전달
END //
DELIMITER ;
- DELIMITER: 여러 명령어들을 하나로 묶어줄때 사용
<PROCEDURE 실행>
CALL CST_GEN_ADDR_IN('MAN', 'SEOUL'); >>> (매개변수값)
<PROCEDURE 삭제>
DROP PROCEDURE CST_GEN_ADDR_IN;
OUT 매개변수
DELIMITER //
CREATE PROCEDURE CST_GEN_ADDR_IN_CNT_MEM_OUT( IN INPUT_A VARCHAR(20), INPUT_B VARCHAR(20), OUT CNT_MEM INT(매개변수 타입) )
BEGIN
SELECT COUNT(MEM_NO) >>> IN 매개변수의 조건이 WHERE로 전달되고 이에 따른 결과값인 회원수가 INTO(OUT 매개변수)를 통해 반환된다.
INTO CNT_MEM >>> OUT 매개변수의 결과값을 반환하는 INTO 명령어
FROM CUSTOMER
WHERE GENDER = INPUT_A
AND ADDR = INPUT_B;
END //
DELIMITER ;
CALL CST_GEN_ADDR_IN_CNT_MEM_OUT('WOMEN', 'INCHEON', @CNT_MEM);
>>> (IN매개변수1, IN매개변수2, OUT매개변수)
SELECT @CNT_MEM; >>> OUT 매개변수값 조회
INOUT 매개변수
DELIMITER //
CREATE PROCEDURE IN_OUT_PARAMETER( INOUT COUNT INT)
BEGIN
SET COUNT = COUNT + 10; >>> IN매개변수(COUNT)인 동시에 +10이 되어 새로운 결과값을 반환
END //
DELIMITER ;
SET @counter = 1; >>> 변수 1 생성
CALL IN_OUT_PARAMETER(@counter);
SELECT @counter; >>> 값으로 11(10+1)이 나옴
4-4. 데이터 마트: 분석에 필요한 데이터를 가공한 분석용 데이터
- 요약 변수: 수집된 데이터를 분석에 맞게 종합한 변수(기간별 구매 금액, 횟수, 수량, 등)
- 파생 변수: 사용자가 특정 조건 또는 함수로 의미를 부여한 변수(연령대, 선호 카테고리, 등)
<회원 구매정보 임시테이블>
CREATE TEMPORARY TABLE CUSTOMER_PUR_INFO AS
SELECT A.MEM_NO, A.GENDER, A.BIRTHDAY, A.ADDR, A.JOIN_DATE
,SUM(B.SALES_QTY * C.PRICE) AS 구매금액
,COUNT(B.ORDER_NO) AS 구매횟수
,SUM(B.SALES_QTY) AS 구매수량
FROM CUSTOMER AS A
LEFT
JOIN SALES AS B
ON A.MEM_NO = B.MEM_NO
LEFT
JOIN PRODUCT AS C
ON B.PRODUCT_CODE = C.PRODUCT_CODE
GROUP
BY A.MEM_NO, A.GENDER, A.BIRTHDAY, A.ADDR, A.JOIN_DATE;
<생년월일 -> 나이(FROM절) -> 연령대>
<회원 연령대 임시테이블>
CREATE TEMPORARY TABLE CUSTOMER_AGEBAND AS
SELECT *
,CASE WHEN 나이 < 10 THEN '10대 미만'
WHEN 나이 < 20 THEN '10대'
WHEN 나이 < 30 THEN '20대'
WHEN 나이 < 40 THEN '30대'
WHEN 나이 < 50 THEN '40대'
ELSE '50대 이상' END AS 연령대
FROM (
SELECT *
,2021-YEAR(BIRTHDAY) +1 AS 나이
FROM CUSTOMER
)AS A;
- CASE WHEN 함수 사용시 주의할 점으로 순차적으로 실행되기 때문에 40대, 20대, 10대와 같은 순서로 작성할 경우 40대 값만 출력되고 20대와 10대의 값은 출력되지 않는다.
<회원 구매정보 + 연령대 임시테이블>
CREATE TEMPORARY TABLE CUSTOMER_PUR_INFO_AGEBAND AS
SELECT A.*
,B.연령대
FROM CUSTOMER_PUR_INFO AS A
LEFT
JOIN CUSTOMER_AGEBAND AS B
ON A.MEM_NO = B.MEM_NO;
<회원 구매정보 + 연령대 + 선호 카테고리 임시테이블>
CREATE TEMPORARY TABLE CUSTOMER_PUR_INFO_AGEBAND_PRE_CATEGORY AS
SELECT A.*
,B.CATEGORY AS PRE_CATEGORY
FROM CUSTOMER_PUR_INFO_AGEBAND(구매정보 + 연령대) AS A
LEFT
JOIN CUSTOMER_PRE_CATEGORY(선호 카테고리) AS B
ON A.MEM_NO = B.MEM_NO;
<회원 분석용 데이터 마트 생성(회원 구매정보 + 연령대 + 선호 카테고리 임시테이블)>
CREATE TABLE CUSTOMER_MART AS
SELECT *
FROM CUSTOMER_PUR_INFO_AGEBAND_PRE_CATEGORY;
<회원 및 카테고리별 구매횟수 순위(FROM절 서브쿼리) + 구매횟수 순위 1위만 필터링(WHERE)>
<회원 선호 카테고리 임시테이블>
CREATE TEMPORARY TABLE CUSTOMER_PRE_CATEGORY AS
SELECT *
FROM (
SELECT A.MEM_NO
,B.CATEGORY
,COUNT(A.ORDER_NO) AS 구매횟수
,ROW_NUMBER() OVER(PARTITION BY A.MEM_NO ORDER BY COUNT(A.ORDER_NO) DESC) AS 구매횟수_순위
FROM SALES AS A
LEFT
JOIN PRODUCT AS B
ON A.PRODUCT_CODE = B.PRODUCT_CODE
GROUP
BY A.MEM_NO
,B.CATEGORY
)AS A
WHERE 구매횟수_순위 = 1;
데이터 정합성: 데이터가 서로 모순 없이 일관되게 일치함을 나타낼 때 사용
- 데이터 마트의 회원 수의 중복은 없는가? DISTINCT
- 데이터 마트의 요약 및 파생변수의 오류는 없는가?
- 데이터 마트의 구매자 비중(%)의 오류는 없는가?
- DISTINCT: 중복 없이 행의 개수 집계
SELECT COUNT(MEM_NO)
,COUNT(DISTINCT MEM_NO)
FROM CUSTOMER_MART;
<회원(1000005)의 구매정보: 구매금액: 408000 / 구매횟수: 3 구매수량: 14>
아래의 출력값이 위의 값과 동일한지 비교
SELECT SUM(A.SALES_QTY * B.PRICE) AS 구매금액
,COUNT(A.ORDER_NO) AS 구매횟수
,SUM(A.SALES_QTY) AS 구매수량
FROM SALES AS A
LEFT
JOIN PRODUCT AS B
ON A.PRODUCT_CODE = B.PRODUCT_CODE
WHERE MEM_NO = '1000005';
<회원(Customer) 테이블 기준, 주문(Sales) 테이블 구매 회원번호 LEFT JOIN 결합>
<구매여부 추가>
<구매여부별, 회원수>
SELECT 구매여부
,COUNT(MEM_NO) AS 회원수
FROM (
SELECT *
,CASE WHEN B.MEM_NO IS NOT NULL THEN '구매'
ELSE '미구매' END AS 구매여부
FROM CUSTOMER AS A
LEFT
JOIN (
SELECT DISTINCT MEM_NO >>> '중복없이 구매한 회원번호' 테이블
FROM SALES
)AS B
ON A.MEM_NO = B.MEM_NO
)AS A
GROUP
BY 구매여부;
/* 확인(미구매: 1459 / 구매: 1202) */
SELECT *
FROM CUSTOMER_MART
WHERE 구매금액 IS NULL; >>> 미구매
SELECT *
FROM CUSTOMER_MART
WHERE 구매금액 IS NOT NULL; >>> 구매
강의 내용 메모와 복습용으로 작성된 글입니다.
'독학으로 취업 문 뿌수기 > SQL' 카테고리의 다른 글
[SQL을 이용해 데이터 분석하기] 제품의 가치 분석하기 (제품 성장률 분석) (0) | 2022.02.07 |
---|---|
[SQL을 이용해 데이터 분석하기] 고객의 구매 현황 및 패턴 분석하기 (재구매율 및 구매주기 분석) (0) | 2022.02.07 |
[SQL을 이용해 데이터 분석하기] 고객 가치 평가모형 분석 (RFM 분석) (0) | 2022.02.07 |
[SQL을 이용해 데이터 분석하기] 회원 프로파일 분석 (0) | 2022.02.07 |