반응형


안녕하세요!


오늘은 SQL 분석함수에 대해 다뤄보도록 하겠습니다!



분석함수란,


기본 함수로는 구현하기 어려운 데이터의 분석을 쉽게 도와주는 함수입니다.



출처: https://www.mbs.ac.uk



1. RANK 함수


: data 의 순위를 출력하는 함수입니다.


순위 기준 값이 같은 행은 순위도 동일하게 결정됩니다.


순위가 동일한 행의 수를 동일한 순위에 추가하여 다음 순위를 계산하기 때문에 순위가 연속된 수가 아닐 수도 있습니다.


예를 들어, 두 행의 순위가 1로 결정되면 다음 순위는 3입니다.


구문


RANK ( ) OVER

 (

 [ PARTITION BY expr_list ]

 [ ORDER BY order_list ]

 ) 



( ) 


함수에 인수가 없지만 빈 괄호가 필요합니다.


OVER


이후 절에 대하여 rank를 확장한다는 의미가 있습니다.


PARTITION BY expr_list


(선택) PARTITION 즉, 분할을 한다는 의미의 조건절 입니다.

RANK의 조건을 정의하는 하나 이상의 표현식입니다.


ORDER BY order_list 


(선택) 순위 값의 기준이 되는 열을 정의합니다. PARTITION BY를 지정하지 않으면 ORDER BY가 전체 테이블을 사용합니다. 즉, ORDER BY가 생략되면 모든 행의 반환 값은 1입니다.


(ORDER BY에서 고유한 순서를 지정하지 않으면 행의 순서는 비확정적입니다.)



반환유형


INTEGER (즉, RANK에 해당하는 숫자)


구 문 출 처: AWS  



활용하기


아래와 같은 COLUMN을 갖고 있는 EMP라는 테이블이 있다고 가정합시다.


EMPNO

ENAME

JOB

SAL

DEPTNO

 

참고: 테이블 스키마를 확인하고 싶을 때

--> SQL>  desc 테이블명;



이 테이블에 대해 아래의 쿼리를 실행해 봅니다.


  SQL> SELECT * FROM EMP;



<결과>


EMPNO

ENAME

JOB

SAL

DEPTNO

 1

 A

 SALESMAN

 1250

 10

 2

 B

 SALESMAN

 1600

 10

 3

 C

 MANAGER

 3000

 20

 4

 D

 CLERK

 1100

 20

 5

 E

 ANALYST

 3000

 30

 6

 F

 ANALYST

 3000

 30

 7

 G

 CLERK

 1300

 30

 8

 H

 MANAGER

 2450

 10

 9

 I

 SALESMAN

 1500

 10



문제1. 이름, 연봉, 순위를 출력하는데

순위는 연봉이 높은 순서로 출력되게 하시오.




추가)


DENSE_RANK 함수와의 비교:


한가지 측면에서 RANK와 DENSE_RANK가 다릅니다.


DENSE_RANK에서는 2개 이상의 행에서 순위가 동일하면 순위 값의 순서에도 빈자리가 없습니다.


예를 들어 두 행의 순위가 1로 결정되면 다음 순위는 2입니다.


(rank의 경우 두 행의 순위가 1로 결정되면 다음 순위는 3입니다.)





2. PIVOT 함수


: 세로(ROW)로 출력되는 결과를 가로(COLUMN)로 출력하는 함수입니다.



관계형 테이블은 다음과 같이 행과 열로 구성됩니다.


EMPNO

ENAME

JOB

SAL

DEPTNO

 1

 A

 SALESMAN

 1250

 10

 2

 B

 SALESMAN

 1600

 10

 3

 C

 MANAGER

 3000

 20

 4

 D

 CLERK

 1100

 20

 5

 E

 ANALYST

 3000

 30

 6

 F

 ANALYST

 3000

 30

 7

 G

 CLERK

 1300

 30

 8

 H

 MANAGER

 2450

 10

 9

 I

 SALESMAN

 1500

 10



문제2. 우선 부서별로 총 월급의 합을 출력해보겠습니다.


 SQL> SELECT DEPTNO, sum(SAL)

              FROM EMP

              GROUP BY DEPTNO;



<결과>


DEPTNO 

SUM(SAL) 

 10

 1250 +  1600 + 2450 + 1500

 20

 3000 + 1100

 30

 3000 + 3000 + 1300



문제3. 과연 이 테이블을 아래와 같이 만드는 방법이 있을까요?


10 

20 

30 

1250 +  1600

   + 2450 + 1500

3000 + 1100

 3000 + 3000 + 1300





참고)


 PIVOT함수를 이용할 때, FROM절에서 SELECT문을 서브쿼리로 이용하여야합니다.

 또한 SELECT 서브쿼리문에서는 결과를 보기위해 필요한 컬럼만을 선별합니다.



원리 설명



추가)


UNPIVOT:


가로(COLUMN)을 세로(ROW)로 출력하는 함수



아래의 간단한 예시를 통해 이해해보도록 합시다!



[EMP2 테이블]


DEPTNO 

A

B

C

D

E

F

G

H

I

10

1250

1600

 

 

 

 

 

2450

1500

20

 

 

3000

1100

 

 

 

 

 

30

 

 

 

 

3000

3000

1300

 

 



문제4. ENAME, DEPTNO, SAL COLUMN으로 테이블을 출력하세요




결과


DEPTNO 

ENAME

SAL

10

A

1250

10

B

1600

10

H

2450

10

I

1500

20

C

3000

20

D

1100

30

E

3000

30

F

3000

30

G

1300




그렇다면 PIVOT 함수는 왜 필요할까요?


임의의 관계현 테이블에 대한 크로스탭 리포트를 생성할 수 있습니다.


UNPIVOT 연산자를 사용하면 임의의 크로스탭 리포트를 정규 관계형 테이블로 변환하는 것이 가능합니다.


참고) PIVOT은 출력결과를 일반 텍스트 또는 XML 포맷으로 반환합니다.



오늘은 유독 글쓰기가 힘드네요


월요병인가 봅니다..


내일은 보다 날씨도, 뇌도 상쾌한 하루가 되길 기대해봅니다!



이 글이 도움되셨다면 아래 공감 꾹~ 






반응형
반응형

출처: https://www.gettyimages.com



그룹함수란 무엇일까요?



그룹함수는 여러 개의 행 데이터를 집합 연산을 수행하여


하나의 결과로 출력하는 함수입니다!





 1. MAX: 최대값을 출력하는 함수


 2. MIN: 최소값을 출력하는 함수


 3. SUM: 총합을 구하는 함수


 4. AGE: 평균값을 구하는 함수


 5. COUNT: 테이블의 행의 수를 세는 함수


 이외에 STDDEV, VARIANCE 함수도 포함합니다.



위의 함수는 모두 복수행 함수(그룹함수)입니다.


복수행 함수의 특징을 2가지를 살펴보겠습니다.



우선, 설명을 원활히 하기 위해 아래와 같이 EMP 테이블이 있다고 가정하겠습니다.


사원명

나이

직업

연봉 

보너스

 A

 35

  NULL

 NULL

 

 B

 34

  SALESMAN

 1600

 300

 C

 38

  PRESIDENT

 5000

 

 D

 36

  SALESMAN

 1400

 0

 E

 39

  ANALYST

 3000

 

 F

 32

  SALESMAN

 1350

 500

 G

 37

  MANAGER

 2850

 

 H

 35

  ANALYST

 3000

 

 I

 36

  SALESMAN

 1700

 1400




첫번째 특징, NULL 값을 무시합니다.



문제1. 전체 직업의 평균 연봉을 알고싶다.


 SELECT avg( 연봉 )

FROM emp;


결과a. 1600 + 5000 + 1400 + 3000 + 1350 + 2850 + 3000 + 1700 / 8


결과b. 1600 + 5000 + 1400 + 3000 + 1350 + 2850 + 3000 + 1700 / 9




그렇다면 결과 b처럼 연봉컬럼에서 null값을 가진 A도 포함하여 계산하고 싶다면 어떻게 해야할까요?



바로 이때 사용할 수 있는 함수는


 NVL, NVL2, COALESCE, CASE, DECODE 함수 사용할 수 있습니다.


저는 NVL함수를 이용하여


결과b처럼 전체 사원 수로 출력되도록 SQL문을 작성해보겠습니다.



  SELECT avg( nvl ( 연봉, 0 ) )

FROM emp;



nvl 함수를 이용하면 null 값을 0 대신하여 출력할 수 있습니다.


따라서 결과는 0 + 1600 + 5000 + 1400 + 3000 + 1350 + 2850 + 3000 + 1700 / 9 로 출력됩니다.




문제2. 아래의 두 SQL의 결과는 같을까? 다를까?


SQL1> SELECT sum( 보너스 ) from emp;


SQL2> ELECT sum( nvl( 보너스, 0) ) from emp;





하지만 현재 emp 테이블에서


null 값이 많이 들어있는 보너스와 같은 컬럼의 경우 


두번째 SQL 문과 같이 null 값을 0 으로 바꾸어 계산한다면


속도면에서 성능이 떨어지게 되겠죠?



결국 SQL의 성능을 생각한다면


첫 번째 SQL과 같이 SQL을 작성해야합니다!




두번째 특징, 각각은 GROUP BY절과 함께 사용할 수 있습니다.



문제1. 직업이 SALESMAN인 사원들 중에서 최대 월급을 알고싶습니다.




WHERE 절은 데이터 검색 조건을 기술하는 절입니다.


따라서 위의 경우 직업이 SALESMAN 인 사원들을 의미합니다.



결론적으로 위의 SQL을 해석하면


① 직업이 SALESMAN인 사원들을 검색 조건으로,

즉 직업이 SALESMAN인 사원만을 선택하여


② 최대값을 구하는 함수를 사용하여 최대 월급을 구하는 것입니다.




문제2. 직업과 직업별 최대 연봉을 알고 싶습니다.




GROUP BY절의 역할은 직업 data를 그룹핑하는 것입니다.


따라서 직업별로 어떠한 값을 구하고자 할 때는 GROUP BY 함수를 이용하여 구할 수 있습니다.



여기서 잠깐!


GROUP BY절에서 조건을 기술할 수 있는 절은 무엇일까요?


 a. WHERE절


 b. HAVING절





그 이유는 실행 순서와 관련이 있습니다.



이해를 위한 추가문제! 아래의 SQL의 실행순서는 어떻게 될까요?


 

 ⓐ SELECT절


 ⓑ FROM절


 ⓒ WHERE절


 ⓓ GROUP BY절


 ⓔ HAVING절


 ⓕ ORDER BY절

 


참고) 위의 순서는 코드순서입니다.

 




추가문제를 통해 알 수 있듯


GROUP BY절은 WHERE절 이후에 실행됩니다.


즉, WHERE절에서 실행되는 순간에는  GROUP BY를 통한 데이터 그룹핑은 일어나지 않습니다.



따라서 GROUP BY를 통한 결과값을 갖는 그룹함수는 HAVING절로 검색조건을 줄 수 있습니다.



오늘은 여기까지!


주말엔 쉽니다~ 월요일에 다시 만나요 우리~




반응형
반응형

DB출처: http://www.thisisgame.com



안녕하세요!


오늘은 '날짜형변환' 에 대해 다뤄보도록 하겠습니다.




날짜형이란 무엇일까요?



우선, 데이터 유형의 변환은 크게 2가지 암시적 형변환과 명시적 형변환으로 나뉩니다.



암시적형변환은  오라클 데이터베이스의 장점이자 단점이라고 볼 수 있습니다.



문제1. 과연, 아래의 SQL문은 과연 실행이 될까요?


 Slect ename, sal

           From 테이블명

           Where sal like '35%';


힌트) 


sal은 연봉을 의미하며 숫자 data가 들어있습니다.


'35%'는 ' ' 싱글쿼테이션으로 감싸져 있으니 문자형이라는 것을 쉽게 알아챌 수 있으셨겠죠?


( 만약 LIKE문을 모르신다면 여기에서 확인하시고 돌아오셔도 됩니다.)





위와 같은 경우를 암시적 형변환이라고 합니다.


어떤 DB에서는 위와같은 경우 형이 맞지 않는 data끼리를 비교하였기 때문에 오류가 발생합니다.


하지만, 오라클의 경우에는 오류가 나지 않기 때문에 형변환으로 많은 시간이 걸린다는 단점이 있습니다.





다음으로 명시적 형변환이 있습니다. 이는 우리가 임의로 데이터 유형을 변경시키는 것입니다.



명시적 형변환은 3가지가 있습니다.


1. to_char: 문자형으로 형변환하는 함수


2. to_number: 숫자형으로 형변환하는 함수


3. to_date: 날짜형으로 형변환하는 함수



오늘은 앞서 언급한 것과 같이 날짜형을 변환하는 방법에 대해 알아보겠습니다.




문제2. 81년 9월 10일에 입사한 사원들의 이름(ename)과 입사일(hiredate)을 알고싶습니다.






그럼 여기서 궁금증이 생깁니다.


과연 어떤 방법이 제일 간단하면서 빠를까요?




사실 그 질문보다 먼저 해야하는 질문이 있습니다.


과연 어떤 방법이 제일 성능이 떨어지는 방법인가요?



그것은 바로 좌변을 가공하는 이와같은 방법입니다.


 SELECT ename, hirdate

FROM 테이블이름

WHERE to_char(hiredate, 'RR/MM/DD') = '81/09/10';



이것은 강제로 날짜 형식을 변경시켜서 찾는 여러 방법 중


실제로 많이 사용하지만 SQL 속도면에서 가장 좋지 않은 방법이라고 할 수 있습니다.




WHERE 조건에서 좌변을 가공하면 인덱스가 사용되지 않습니다. 


즉 처음부터 끝까지 비교를 해야하는거죠 (FULL TABLE SCAN을 하게됩니다.)

출처: 한국데이터진흥원


다음으로 새로 DB에 접속할 때마다 날짜형을 변환하는 다음과 같은 방법이 있겠죠.


 ALTER SESSION SET nls_date_format = 'RR/MM/DD';



그것도 귀찮다면!



아래와 같이 날짜형 데이터의 형변환을 하는 습관을 들이시는 것은 어떨까요?


SELECT ename, hiredate

FROM 테이블명

       WHERE hiredate = to_date('81/09/10') 






오늘도 수고하셨습니다.


매일매일 SQL을 공부하며 성장하는 으니입니다!


앞으로도 화이팅합시다!!



만약 위포스팅에서 잘못된 부분이 있다면 댓글로 알려주세요~



이 글이 도움되셨다면 아래 공감 꾹~ 





반응형
반응형


SQL이란,



 관계형 데이터베이스 관리 시스템에서


 자료의 검색 및 관리 등을 위해 설계된 프로그래밍 언어입니다.


출처: 위키백과




이러한 SQL 에는 다양한 함수가 존재하는데요.


이러한 함수는 크게 '단일 행 함수'와 '복수 행 함수'로 나뉠 수 있습니다.






오늘은 단일 행 함수의 속하는 다양한 함수 중 문자함수에 대해 알아보겠습니다.





데이터 검색을 할 때 함수가 필요한 이유는 무엇일까요?



그 이유는!



함수를 이용하면 더 다양하게 데이터를 검색할 수 있기 때문입니다.



문제를 통해 이 사실을 확인합시다.


현재 DB에 있는 EMAIL의 형식을 아래와 같이 가정합니다.


                       '아이디 @ naver.com'

'아이디 @ daum.com'

'아이디 @ gmail.com'


 .

 .

 .

 .




과연 함수 없이 다음 문제를 풀 수 있을까요?



문제1. 이메일에서 @가 몇 번째 철자에 있는지 알려주세요!



문제2. 내 이메일 주소를 다른 사람이 알 수 없도록 다른 철자로 변경해주세요!



문제3. 이메일을 입력하다 모르고 처음에 공백을 넣어서 찾을 수가 없습니다. 해결해주세요.




이때 사용하는 함수를 각각 소개하겠습니다.


문제1. 이메일에서 @가 몇 번째 철자에 있는지 알려주세요!






이 때 사용하는 함수가 바로 INSTR 함수입니다.


instr함수는 특정 철자가 단어에서 몇 번째 철자인지 확인하는 함수죠!


(단, 처음 나오는 특정 철자의 자리를 알려준답니다!)



형식: 


 INSTR (string, substring [, position ] )



'string'


 입력할 문자열을 지정하는 부분입니다.



'substring'


 위치를 반환할 문자열을 지정하는 것입니다.



'position'


 탐색을 시작할 string의 위치를 나타내며, 문자 재수 단위로 지정됩니다.

 이 인자가 생략되면 기본값인 1이 적용됩니다. 즉, 선택사항이죠



반환 값은 INT 형식으로 숫자가 return됩니다.


출처: CUBRID




문제2. 내 이메일 주소를 다른 사람이 알 수 없도록 다른 철자로 변경해주세요!





물론 더 좋은 보안 시스템을 이용할 수도 있죠.




하지만,


제가 여기서 강조하고 싶은 부분은 바로 'regexp_replace'함수 입니다.



regexp_replace 함수는 여러개의 철자를 한번에 다른 철자로 변경하는 함수입니다.



형식:


REGEXP_RPLACE ( source_string, pattern [ , replace_string [ , position] ] ) 



'source_string'


 열 이름 같이 검색할 문자열 표현식입니다.



'pattern'


 SQL 표준 정규 표현식 패턴을 나타내는 문자열 리터럴입니다.



'replace_string'


 발견되는 패턴을 각각 변형할 문자열 표현식(열 이름 등) 입니다. 기본값은 빈 문자열 입니다.



'position'


source_string 내에서 검색을 시작할 위치를 나타내는 양의 정수입니다. 이 위치는 바이트가 아닌 문자 수를 기준으로 하기 때문에 멀티바이트 문자도 단일 문자로 계산됩니다. 기본 값은 1입니다.



반환 값은 VARCHAR 형식으로 문자가 return 됩니다.


출처: AWS




추가) 만약 특정 철자만 다른 철자로 변경하고 싶다면 어떻게 해야할까요?



바로 replace 함수를 이용하면 됩니다.


비교해서 알아두면 좋습니다.


replace 함수와 regexp_replace 함수의 차이를 찾아보도록해요~

여기 (엄청 많은 포스팅이 있습니다!)




마지막 문제!!


문제3. 이메일을 입력하다 모르고 처음에 공백을 넣어서 찾을 수가 없습니다. 해결해주세요.





여기서 소개할 함수는 'TRIM' 함수 입니다.


TRIM함수는 특정 철자를 잘라내는 함수 입니다.

TRIM함수의 종류와 기능은 아래와 같습니다.


TRIM()

--> 양쪽 공백을 잘라내겠다

RTRIM()

--> 오른쪽 공백을 잘라내겠다.

LTRIM()

--> 왼 공백을 잘라내겠다.



형식:


TRIM( [ BOTH ] [ 'characters' FROM ] string] ) 



'BOTH'


LEADING : 왼쪽에서 제거  


TRAILING : 오른쪽에서 제거


BOTH : 양쪽에서 제거


특별히 설정해주는 값이 없으면 기본값은 BOTH 입니다.



'characters'


문자열에서 잘라낼 문자입니다. 이 파라미터를 생략하면 공백이 잘립니다.


'string'


자르기 대상이 되는 문자열입니다.



반환 값은 varchar 또는 char 문자열을 return 합니다.


출처: aws, 좋은 블로그






우와! 드디어 끝!!!


여기까지 보신 분들 오늘 남은 시간도  화이팅 합시다!



이 글이 도움되셨다면 아래 공감 꾹~ 



반응형

+ Recent posts