<commit_before>---
layout: post
title: 오라클SQL - 16/10/25
category: acorn수업
---

## SYSDATE 함수  
- 날짜 + 날짜는 오류발생  
- 날짜 - 날짜는 사이의 일수가 나온다  
- 날짜에 숫자를 더하거나 빼면 날짜가 나온다  

```
-- MYSQL에서는 SYSDATE()
SELECT SYSDATE FROM DUAL;

-- 날짜연산
SELECT SYSDATE-1 FROM DUAL; 
SELECT SYSDATE, HIREDATE, MONTHS_BETWEEN(SYSDATE, HIREDATE) FROM EMP;


SELECT HIREDATE, ADD_MONTHS(HIREDATE, 6) FROM EMP;
SELECT LAST_DAY(HIREDATE) FROM EMP;

-- SYSDATE다음에 AS가 생략된 것
SELECT SYSDATE TODAY, LAST_DAY(SYSDATE) LASTDAY FROM DUAL;

-- MONTH_BETWEEN은 A1과 A2 사이의 달의 수를 NUMBER형 타입으로 변환
SELECT HIREADTE, NEXT_DAY(HIREDATE, ‘금’) FROM EMP;
```

---

## 형 변환 함수

```
SELECT SYSDATE TO_DATE(“2006/01/01, YYYY/MM/DD’) FROM DUAL;

-- TO_CHAR: TO_CHAR함수는 DATE형, NUMBER형을 VARCHAR2형으로 변환
SELECT TO_CHAR(SYSDATE, ‘MONTH’) CHARTEST FROM DUAL;

-- TO_DATE: TO_DATE함수는 CHAR, VARCHAR2형을 DATE타입으로 변환
SELECT TO_DATE(‘2000/06/16’, ‘RRRR/MM/DD’) FROM DUAL;

-- TO_NUMBER: TO_NUMBER함수는 CHAR, VARCHAR2의 데이터 타입을 숫자형식으로 변환
SQL> SELECT TO_NUMBER(‘120616’) FROM DUAL;

SELECT SYSDATE TO_DATE(‘2016/01/01’) FROM DUAL;    
SELECT SYSDATE TO_DATE(‘00’, ‘YY’) FROM DUAL; -- → 2000
SELECT SYSDATE TO_DATE(‘50’, ‘YY’) FROM DUAL; -- → 2050
SELECT SYSDATE TO_DATE(‘00’, ‘RR’) FROM DUAL; -- → 2000
SELECT SYSDATE TO_DATE(‘50’, ‘RR’) FROM DUAL; -- → 1950

SELECT
  TO_CHAR(SYSDATE, ‘YY/MM/DD’) DATE1,
  TO_CHAR(SYSDATE, ‘YYYY.MM.DD’) DATE2,
  TO_CHAR(SYSDATE, ‘MONTH DD. YYYY’) DATE3,
  TO_CHAR(SYSDATE, ‘DY DD MON YY’) DATE4,
  TO_CHAR(SYSDATE, ‘DAY MON DD’) DATE5
FROM DUAL;

SELECT P_NAME, TO_CHAR(HIREDATE ‘YYYY”년” MM”월” DD”일” DAY’) FROM EMP;

SELECT SYSDATE FROM DUAL;

SELECT TO_CHAR(1234,'09,999') NUMBER1, TO_CHAR(1234.56,'99,999.99') NUMBER2, TO_CHAR(1234,'$99,999') NUMBER3, TO_CHAR(1234,'L99,999') NUMBER4 FROM DUAL;
```

---

## DECODE

```
SELECT ENAME, DEPTNO, 
DECODE
(DEPTNO,
  10, 'ACCOUNTING', 
  20, 'RESEARCH', 
  30, 'SALES', 
  40, 'OPERATIONS') DAME 
FROM EMP;
```

문제1) 직급에 따라 급여를 인상하도록 하자. 직급이 ‘ANALYST’인 사원은 5%, ‘SALESMAN’인 사원은 10%, ‘MANAGER’인 사원은 15%, ‘CLERK’인 사원은 20% 인상한다. (SAL에 UPSAL을 만들어야 함)  

```
-- !!곱하기 문자가 여기서 자동변환이 된다.
-- mysql에서 한 것
select job, sal, 
  case 
  when job='analyst' then sal*1.05 
  when job='salesman' then sal*1.1
  when job='manager' then sal*1.15
  when job='clerk' then sal*1.2
  else sal 
  end as upsal --별칭 설정
from emp;

-- 오라클에서 한 것
SELECT EMPNO, ENAME, JOB, SAL, 
  decode(job, 'analyst', sal * 1.05, 'salesman', sal * 1.1, 'manager', sal * 1.15, 'clerk', sal * 1.2) as salnic 
from emp;
```

---

## 조건에 따라 서로 다른 처리가 가능한 CASE 함수

- 단순한 판단에 사용 - DECODE
- 여러 조건 붙이는 것이 가능 - CASE

문제2) deptno에 따라 부서이름을 붙이기(10 - accouting, 20 - research, 30 - sales, 40 - operations) + 이름, 부서번호 출력  

```
SELECT ENAME, DEPTNO,
  CASE WHEN DEPTNO = 10 THEN ‘ACCOUNTING’
      WHEN DEPTNO = 20 THEN ‘RESEARCH’
      WHEN DEPTNO = 30 THEN ‘SALES’
      WHEN DEPTNO = 40 THEN ‘OPERATIONS’
    END DNAME
FROM EMP;


select ename, deptno, case 
        when deptno=10 then 'accouting'
        when deptno=20 then 'research'
        when deptno=30 then 'sales'
        when deptno=40 then 'operations'
        else 'no'
        end as deptname
from emp;
```

---

## 그룹 함수

- 그룹함수란 여러 행 또는 테이블 전체의 행에 대해 함수가 적용되어 하나의 결과값을 가져오는 함수
- GROUP BY 절을 이용하여 그룹당 하나의 결과가  주어지도록 그룹화
- HAVING 절을 사용하여 그룹 함수를 가지고 조건비교 가능
- COUNT((*))를 제외한 모든 그룹함수는 NULL갑을 고려하지 않음
```
SELECT COUNT(COMM) FROM EMP;
SELECT COUNT(COMM)FROM EMP WHERE DEPTNO=10;
SELECT COUNT(*) FROM EMP;
```
- 그룹함수를 사용할 때에는 단일 레코드에 대한 내용을 같이 출력할 수 없다.
```
SELECT ENAME COUNT(*) FROM EMP; -- 불가능
```
- MIN, MAX 그룹함수는 모든 자료형에 대해 사용할 수 있음
```
SELECT SUM(SAL) FROM EMP;
SELECT AVG(SAL), STDDEV(SAL), VARIANCE(SAL) FROM EMP;
SELECT MAX(SAL), MIN(SAL) FROM EMP;
```

### GROUP BY 절

문제3) 부서번호로 정렬된 부서번호, 평균임금 테이블을 출력하라  
```
SELECT DEPTNO, AVG(SAL) FROM EMP GROUP BY DEPTNO;
```
//소수점 둘째자리에서 반올림하여 출력해볼 것  

문제4) 부서별로 커미션을 받는 사원들의 수를 계산  
1. 사원들의 수를 출력  
2. 부서목록 출력  
```
select count(comm) from emp group by deptno;

select deptno, count(comm) "커미션 받는 사원" from emp group by deptno;

-- 틀린 것 SELECT DEPTNO, COUNT(*), COUNT(COMM) FROM EMP GROUP BY DEPTNO;
```

문제5) 부서별 최대 급여와 최소 급여를 산출하기 위한 예제  
- select max(sal), min(sal) from emp; 를 하면 전체 데이터 중에서 최대, 최소를 구한다. (1행 2열)
- '부서별'로 구하려면 (부서가3개이므로 3행 2열이 되어야 한다) group by로 부서에 대한 값이 필요
- +deptno에 대한 정보도 같이 출력한다.

```
select deptno, max(sal), min(sal) from emp group by deptno;
```<commit_msg>Update 2017-04-25-acorn_day12_161025.md<commit_after>---
layout: post
title: 오라클SQL - 16/10/25
category: acorn수업
---

## SYSDATE 함수  
- 날짜 + 날짜는 오류발생  
- 날짜 - 날짜는 사이의 일수가 나온다  
- 날짜에 숫자를 더하거나 빼면 날짜가 나온다  

```
-- MYSQL에서는 SYSDATE()
SELECT SYSDATE FROM DUAL;

-- 날짜연산
SELECT SYSDATE-1 FROM DUAL; 
SELECT SYSDATE, HIREDATE, MONTHS_BETWEEN(SYSDATE, HIREDATE) FROM EMP;


SELECT HIREDATE, ADD_MONTHS(HIREDATE, 6) FROM EMP;
SELECT LAST_DAY(HIREDATE) FROM EMP;

-- SYSDATE다음에 AS가 생략된 것
SELECT SYSDATE TODAY, LAST_DAY(SYSDATE) LASTDAY FROM DUAL;

-- MONTH_BETWEEN은 A1과 A2 사이의 달의 수를 NUMBER형 타입으로 변환
SELECT HIREADTE, NEXT_DAY(HIREDATE, ‘금’) FROM EMP;
```

---

## 형 변환 함수

```
SELECT SYSDATE TO_DATE(“2006/01/01, YYYY/MM/DD’) FROM DUAL;

-- TO_CHAR: TO_CHAR함수는 DATE형, NUMBER형을 VARCHAR2형으로 변환
SELECT TO_CHAR(SYSDATE, ‘MONTH’) CHARTEST FROM DUAL;

-- TO_DATE: TO_DATE함수는 CHAR, VARCHAR2형을 DATE타입으로 변환
SELECT TO_DATE(‘2000/06/16’, ‘RRRR/MM/DD’) FROM DUAL;

-- TO_NUMBER: TO_NUMBER함수는 CHAR, VARCHAR2의 데이터 타입을 숫자형식으로 변환
SQL> SELECT TO_NUMBER(‘120616’) FROM DUAL;

SELECT SYSDATE TO_DATE(‘2016/01/01’) FROM DUAL;    
SELECT SYSDATE TO_DATE(‘00’, ‘YY’) FROM DUAL; -- → 2000
SELECT SYSDATE TO_DATE(‘50’, ‘YY’) FROM DUAL; -- → 2050
SELECT SYSDATE TO_DATE(‘00’, ‘RR’) FROM DUAL; -- → 2000
SELECT SYSDATE TO_DATE(‘50’, ‘RR’) FROM DUAL; -- → 1950

SELECT
  TO_CHAR(SYSDATE, ‘YY/MM/DD’) DATE1,
  TO_CHAR(SYSDATE, ‘YYYY.MM.DD’) DATE2,
  TO_CHAR(SYSDATE, ‘MONTH DD. YYYY’) DATE3,
  TO_CHAR(SYSDATE, ‘DY DD MON YY’) DATE4,
  TO_CHAR(SYSDATE, ‘DAY MON DD’) DATE5
FROM DUAL;

SELECT P_NAME, TO_CHAR(HIREDATE ‘YYYY”년” MM”월” DD”일” DAY’) FROM EMP;

SELECT SYSDATE FROM DUAL;

SELECT TO_CHAR(1234,'09,999') NUMBER1, TO_CHAR(1234.56,'99,999.99') NUMBER2, TO_CHAR(1234,'$99,999') NUMBER3, TO_CHAR(1234,'L99,999') NUMBER4 FROM DUAL;
```

---

## DECODE

```
SELECT ENAME, DEPTNO, 
DECODE
(DEPTNO,
  10, 'ACCOUNTING', 
  20, 'RESEARCH', 
  30, 'SALES', 
  40, 'OPERATIONS') DAME 
FROM EMP;
```

문제1) 직급에 따라 급여를 인상하도록 하자. 직급이 ‘ANALYST’인 사원은 5%, ‘SALESMAN’인 사원은 10%, ‘MANAGER’인 사원은 15%, ‘CLERK’인 사원은 20% 인상한다. (SAL에 UPSAL을 만들어야 함)  

```
-- !!곱하기 문자가 여기서 자동변환이 된다.
-- mysql에서 한 것
select job, sal, 
  case 
  when job='analyst' then sal*1.05 
  when job='salesman' then sal*1.1
  when job='manager' then sal*1.15
  when job='clerk' then sal*1.2
  else sal 
  end as upsal --별칭 설정
from emp;

-- 오라클에서 한 것
SELECT EMPNO, ENAME, JOB, SAL, 
  decode(job, 'analyst', sal * 1.05, 'salesman', sal * 1.1, 'manager', sal * 1.15, 'clerk', sal * 1.2) as salnic 
from emp;
```

---

## 조건에 따라 서로 다른 처리가 가능한 CASE 함수

- 단순한 판단에 사용 - DECODE
- 여러 조건 붙이는 것이 가능 - CASE

문제2) deptno에 따라 부서이름을 붙이기(10 - accouting, 20 - research, 30 - sales, 40 - operations) + 이름, 부서번호 출력  

```
SELECT ENAME, DEPTNO,
  CASE WHEN DEPTNO = 10 THEN ‘ACCOUNTING’
      WHEN DEPTNO = 20 THEN ‘RESEARCH’
      WHEN DEPTNO = 30 THEN ‘SALES’
      WHEN DEPTNO = 40 THEN ‘OPERATIONS’
    END DNAME
FROM EMP;


select ename, deptno, case 
        when deptno=10 then 'accouting'
        when deptno=20 then 'research'
        when deptno=30 then 'sales'
        when deptno=40 then 'operations'
        else 'no'
        end as deptname
from emp;
```

---

## 그룹 함수

- 그룹함수란 여러 행 또는 테이블 전체의 행에 대해 함수가 적용되어 하나의 결과값을 가져오는 함수
- GROUP BY 절을 이용하여 그룹당 하나의 결과가  주어지도록 그룹화
- HAVING 절을 사용하여 그룹 함수를 가지고 조건비교 가능
- COUNT((*))를 제외한 모든 그룹함수는 NULL갑을 고려하지 않음
```
SELECT COUNT(COMM) FROM EMP;
SELECT COUNT(COMM)FROM EMP WHERE DEPTNO=10;
SELECT COUNT(*) FROM EMP;
```
- 그룹함수를 사용할 때에는 단일 레코드에 대한 내용을 같이 출력할 수 없다.
```
SELECT ENAME COUNT(*) FROM EMP; -- 불가능
```
- MIN, MAX 그룹함수는 모든 자료형에 대해 사용할 수 있음
```
SELECT SUM(SAL) FROM EMP;
SELECT AVG(SAL), STDDEV(SAL), VARIANCE(SAL) FROM EMP;
SELECT MAX(SAL), MIN(SAL) FROM EMP;
```

### GROUP BY 절

문제3) 부서번호로 정렬된 부서번호, 평균임금 테이블을 출력하라  
```
SELECT DEPTNO, AVG(SAL) FROM EMP GROUP BY DEPTNO;
```
//소수점 둘째자리에서 반올림하여 출력해볼 것  

문제4) 부서별로 커미션을 받는 사원들의 수를 계산  
1. 사원들의 수를 출력  
2. 부서목록 출력  

```
select count(comm) from emp group by deptno;

select deptno, count(comm) "커미션 받는 사원" from emp group by deptno;

-- 틀린 것 SELECT DEPTNO, COUNT(*), COUNT(COMM) FROM EMP GROUP BY DEPTNO;
```

문제5) 부서별 최대 급여와 최소 급여를 산출하기 위한 예제  
- select max(sal), min(sal) from emp; 를 하면 전체 데이터 중에서 최대, 최소를 구한다. (1행 2열)
- '부서별'로 구하려면 (부서가3개이므로 3행 2열이 되어야 한다) group by로 부서에 대한 값이 필요
- +deptno에 대한 정보도 같이 출력한다.

```
select deptno, max(sal), min(sal) from emp group by deptno;
```
{'fraction_non_alphanumeric': 0.13423433741839422, 'fraction_numerical': 0.0451265605314397, 'mean_word_length': 3.385735811150176, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4725202', 'n_tokens_mistral': 5157, 'n_tokens_neox': 5574, 'n_words': 1223}