본문 바로가기
Today I learned

2021 02 16 - CASE, CASE, CASE

by soheemon 2021. 2. 16.

집계와 조건분기

-UNION을 사용한 방법

SELECT prefecture, SUM(pop_men) AS pop_men, SUM(pop_won) AS pop_wom
FROM( SELECT prefecture, pop AS pop_men, null AS pop_wom
	  FROM Population
      WHERE gender = '1' --남성
      UNION
      SELECT prefecture, pop AS pop_wom, null AS pop_men
	  FROM Population
      WHERE gender = '2') TMP--여성
GROUP BY prefecture;

-CASE를 사용한 방법

CASE 식을 집계함수 안에 사용하면 필터를 만들 수 있다.

또한 Seq San으로 테이블 풀스캔이 1회로 감소한다.

SELECT prefecture
	SUM(CASE WHEN gender = '1' THEN pop ELSE 0 END) AS pop_men,
    SUM(CASE WHEN gender = '0' THEN pop ELSE 0 END) AS pop_won
FROM Population
GROUP BY prefecture;

2)

UNION을 사용한 방법

SELECT emp_name
	MAX(team) AS team
FROM Employees
GROUP BY emp_name
HAVING COUNT(*) = 1
UNION
SELECT emp_name
	'2개를 겸무' AS team
FROM Employees
GROUP BY emp_name
HAVING COUNT(*) = 2
UNION
SELECT emp_name
	'3개를 겸무' AS team
FROM Employees
GROUP BY emp_name
HAVING COUNT(*) = 3

CASE를 사용한 방법

SELECT emp_name
	CASE WHEN COUNT(*) = 1 THEN MAX(team)	--왜 MAX를쓸까 ㅜ 이유: groupby로 집약했기때문.
    	 WHEN COUNT(*) = 2 THEN '2개를겸무'
         WHEN COUNT(*) >=3 THEN '3개를겸무'
    END AS team
FROM Employees
GROUP BY emp_name;

 

절차 지향형과 선언형

 

집약

GROUP BY 구로 집약했을때 SELECT 구에 입력할 수 있는것은 세가지이다.

- 상수

- GROUP BY 구에서 사용한 집약 키

- 집약함수

 

GROUP BY
집약할때 따라서는 정렬을 사용하기도 한다.(SORT GROUP BY - 오라클의 경우)
GROUP BY 구에 지정되어 있는 필드를 해시 함수를 사용해서 해시키로 변환하고, 같은 해시키를 가진 그룹을 모아 집약하는 방법이다.
해시의 성질상 GROUP BY의 유일성이 높으면 더 효율적으로 작동한다.

자르기

GROUP BY로 집약 말고도 한가지  기능이 있다. 바로 자르기.

모집합인 테이블을 작은 부분 집합들로 분리하는 것.

 

// 첫 문자 알파벳마다 몇명의 사람이 존재하는지 확인.

SELECT SUBSTRING(name, 1, 1) AS label,
		COUNT(*)
FROM Persons
GROUP BY SUBSTRING(name, 1, 1);

 

//파티션

이렇게 GROUP BY 구로 잘라 만든 하나하나의 부분 집합을 수학적으로는 파티션이라고 부른다.

SELECT CASE WHEN age < 20 THEN '어린이'
            WHEN age BETWEEN 20 AND 69 THEN '성인'
            WHEN age >= 70 THEN '노인'
            ELSE NULL END AS age_class,
       COUNT(*)
FROM Persons
GROUP BY CASE WHEN age < 20 THEN '어린이'
            WHEN age BETWEEN 20 AND 69 THEN '성인'
            WHEN age >= 70 THEN '노인'
            ELSE NULL END

        

반복문

SQL은 내부적으로는 반복문을 사용한다.

특정 레코드를 전체의 레코드와 비교하는 로직은 전형적인 '한번에 한 레코드' 사고방식이다.

 

SQL에서는 반복을 어떻게 표현할까?

SQL에서 반복문을 대신하는 수단은 CASE식과 윈도우 함수이다. -> IF-THEN-ELSE 구문에 대응하는 기능이다.

 

SELECT company,
		year,
        sale,
        CASE SIGN(sale - MAX(sale)	--OVER 쓰려고 MAX 쓴듯.
        					OVER( PARTITION BY company
                            		ORDER BY year
                                    ROWS BETWEEN 1 PRECEDING	--현재 레코드에서 직전레코드 1개 지정
                                    		AND 1 PRECEDING
                            	))
        WHEN 0 THEN '='
        WHEN 1 THEN '+'
        WHEN -1 THEN '-'
        ELSE NULL END AS var
FROM Sales;

SIGN 함수는 숫자 자료형을 매개변수로 받아, 음수 -1 양수 1 0이라면 0을 리턴한다.

실행계획 풀스캔 -> 윈도우 함수를 정렬로 실행

 

 

'Today I learned' 카테고리의 다른 글

2021 02 19 - 서브쿼리  (0) 2021.02.19
2021 02 16 - SQL과 반복문  (0) 2021.02.16
2021 02 08  (0) 2021.02.08
2021 02 08 - sql 소소한 정리  (0) 2021.02.08
2021 02 04 - Email Template 수정  (0) 2021.02.04

댓글