기초 데이터 분석을 위한 핵심 SQL 완전 정복

2022. 2. 6. 05:53독학으로 취업 문 뿌수기/SQL

728x90
반응형
SMALL

1-1. SQL과 관계형 데이터베이스

SQL 및 관계형 데이터베이스.pdf
0.24MB


1-2. MySQL과 Workbench

SQL 실습 환경.pdf
0.20MB


1-3 Workbench 살펴보기

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

2. SQL 명령어

SQL 기본 명령어.pdf
0.15MB


2-1. 데이터 정의어(DDL): 테이블을 생성, 변경, 삭제할 때 사용하는 명령어

데이터 정의어(DDL).pdf
0.25MB

  • 테이블은 각 열마다 반드시 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): 데이터를 삽입, 조회, 수정, 삭제할 때 사용하는 명령어

데이터 조작어(DML).pdf
0.20MB

데이터를 삽입하기 전 테이블을 미리 생성해야 한다.

  • 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): 데이터 접근 권한 부여 및 제거할 때 사용하는 명령어

데이터 제어어(DCL).pdf
0.21MB

사용자를 추가하기 위해 먼저 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) 명령어 실행, 취소, 임시저장할 때 사용하는 명령어

트랜젝션 제어어(TCL).pdf
0.26MB

트랜젝션 시작 BIGIN >> 데이터 삽입 INSERT (+수정, 삭제) >> 실행 COMMIT or 취소 ROLLBACK

  • 트랜젝션(Transaction)은 분할할 수 없는 최소 단위이며 논리적인 작업 단위
  • 실행(COMMIT): 모든 작업을 최종 실행 (트랜젝션을 빠져나옴) COMMIT;
  • 취소(ROLLBACK): 모든 작업을 되돌림 ROLLBACK;
  • BEGIN; - 트랜젝션 시작
  • 임시저장(SAVEPOINT): ROLLBACK 저장점을 지정하는 명령어
  • SAVEPOINT S1(임시저장명);
  • ROLLBACK TO S2; - 원하는 지점으로 되돌림

SQL 명령어 단원 정리.pdf
0.19MB


3-1. 데이터 조회(SELECT): 데이터 조작어(DML)이며, 데이터 분석에서 가장 많이 사용되는 명령어

데이터 조회(SELECT).pdf
0.49MB

  • 여러 절들과 함께 사용되어, 분석에 필요한 데이터 조회
  • 절: 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)

테이블 결합(JOIN).pdf
0.35MB

  • 테이블 결합은 두 테이블 관계를 활용하여 테이블을 결합하는 명령어
  • 관계: 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 >>> 주문테이블이 기준
  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문이 있는 명령어

서브 쿼리(Sub Query).pdf
0.28MB

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;

SQL 문법 단원 정리.pdf
0.31MB


4-1. 연산자

연산자 및 함수.pdf
0.51MB

  • 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. 데이터 마트: 분석에 필요한 데이터를 가공한 분석용 데이터

데이터 마트.pdf
0.31MB

  • 요약 변수: 수집된 데이터를 분석에 맞게 종합한 변수(기간별 구매 금액, 횟수, 수량, 등)
  • 파생 변수: 사용자가 특정 조건 또는 함수로 의미를 부여한 변수(연령대, 선호 카테고리, 등)

<회원 구매정보 임시테이블>
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 활용 단원 정리.pdf
0.47MB


강의 내용 메모와 복습용으로 작성된 글입니다.

 

728x90
반응형
LIST