SQL 부서별 인원수 - SQL buseobyeol in-wonsu

like Amazon Web Services

  • 한글자 '_'

select * from s_emp
where name like '박_'; // '박근수' 검색 불가, '박__'으로 해야 가능

  • 여러글자 '*'

select * from s_emp
where name like '박*'; // '박근수' 검색가능

Note DUAL 은 가상 테이블

문자 출력

select chr(65) from dual; // 영어 'A'
select nchr(44032) from dual; // 한글 '가'

날짜 출력

SELECT SYSDATE FROM DUAL; // 오늘 날짜

말일 구하기

SELECT TO_DATE('19/05/01')-1 FROM DUAL; // 익월에서 하루 빼면

월 반올림

SELECT ROUND(SYSDATE,'MONTH') FROM DUAL;

(오늘 4/16일 때)

SELECT ADD_MONTHS(TRUNC(SYSDATE, 'MONTH'),1)-1 FROM DUAL;

TRUNC - 버림 4/1
ADD_MONTHS - 한달 더하기 5/1
-1 하면 - 4월 마지막날 4/30

결과 4/30

날짜-> 문자

SELECT TO_CHAR(SYSDATE, 'yyyy/MM/dd') FROM DUAL;

update시 select 먼저!!!

퀴즈 ) 박구곤이라는 사람의 mailid를 null로 변경하시오

--update s_emp set mailid = null
select * from s_emp;
where name='박구곤';

count(*) vs count(컬럼)시 - null값 고려

select count(*) from s_emp; --e_emp 테이블의 행의 개수 : 25
select count(mailid) from s_emp; --s_emp 테이블의 mailid컬럼의 값의 개수 : 24 // null 값은 카운팅 되지 않음

GROUP BY - 부서별로 그룹화

직책이 사원인 사람들의 평균연봉을 부서별로 구하고 연봉이 높은 순으로 정렬합니다!!!!!!!

select dept_id, AVG(salary) -- 1. 평균연봉을 구한다 from s_emp where title = '사원' -- 2. 사원인 사람들만 group by dept_id -- 3. 부서별로 구한다(dept_id) order by 2 desc; -- 4. 두번째 컬럼AVG(salary)로 내림차순 정렬!

sql 할때 꼭 한두개 정도 평균 확인 해 볼 필요가 있다!
계산기 ㅎㅎㅎ 해보기 크으으으으
쿼리 결과랑 비교해서 값이 맞는지 확인!

Q. 각 부서별 평균 급여를 계산해서 보여주시오

select dept_id, trunc(AVG(salary),2) --1. 평균급여를 구한다. from s_emp group by dept_id --2. 부서별로 구한다 order by 2 desc ;

Q. 각 부서별로 직책이 사원인 직원들의 평균 급여를 계산해서 보여주시오

select dept_id, avg(salary) from s_emp where title = '사원' group by dept_id order by 1;

그룹화 한 경우에는 그룹함수와 group by 에 지정된 컬럼만 사용가능

select dept_id, avg(salary) from s_emp group by dept_id;

Q. 각 지역 별(region_id)로 몇개의 부서가 있는지를 나타내시오

select region_id, count(name) from s_dept -- 1. 몇개부서인지count(name) group by region_id order by region_id; -- 2. 지역별 그룹화

Q. 각 부서별(dept_id)로 평균 급여(avg(salary))를 구하되 평균 급여가 2000 이상(avg(salary)>=2000)인 부서만 나타내시오

select dept_id,avg(salary) from s_emp group by dept_id having avg(salary) >= 2000 -- 그룹함수 조건은 where 절이 아닌 having에 넣는다 ;

직책을 두개 이상 가지고 있는 그룹 평균 연봉을 보여줌

select title, avg(salary), count(*) -- 직책 / 평균연봉 / 직책 수 를 from s_emp group by title -- 직책별로 having count(*) > 2; -- 직책의 개수가 2 초과 하면 출력

Q. 각 직책별(title)로 급여의 총합(sum(salary))을 구하되 직책이 부장인 사람은 제외하시오,

-- 단, 급여 총합이 8000만원 이상인 직책만 나타내며, 급여 총합에 대한 오름차순으로 정렬하시오

select title, sum(salary) from s_emp--1. 급여의 총합 - (sum(salary)) where title not like '%부장' -- 부장인 사람은 제외 group by title--2. 직책별로 - (title) having sum(salary) >= 8000--3. 급여 총합이 8000만원 이상 order by 2 asc;--4. 오름차순

Q. 각 부서별로 직책이 사원인 직원들에 대해서만 평균 급여를 구하시오

select dept_id, avg(salary) from s_emp--1. 평균급여 출력 where title='사원' --3. 직책이 사원 group by dept_id--2. 부서별 ;

Q. 각 부서내에서(dept_id) 각 직책별(title)로 몇명의 인원(count(*))이 있는지 나타내시오

select title, count(*) from s_emp--1. 몇명있는지 출력 group by title--3. 직책별로 그룹화 order by title ;

Q. 각 부서내(dept_id)에서 몇명(count(*))의 직원이 근무하는지를 나타내시오

select dept_id, count(*) from s_emp--1. 몇명있는지 출력 group by dept_id--2. 부서별로 ;

Q. 각 부서별(dept_id)로 급여의 최소값(min(salary))과 최대값(max(salary))을 나타내시오

-- 단, 최소값과 최대값이 같은 부서((min(salary))=(max(salary))는 출력하지 마시오.

select dept_id, min(salary), max(salary) from s_emp --1. 급여의 최소값과 최대값 group by dept_id--2. 부서별로 --having min(salary) not like max(salary)--3. 부서별로 최소값과 최대값이 같으면 출력 안함 having min(salary) <> max(salary)--3. 부서별로 최소값과 최대값이 같으면 출력 안함 order by dept_id;

GROUP BY & HAVING

※ 작성 순서(숫자: 실행순서)

5: SELECT 컬럼명, AS 별칭, 계산식, 함수식 - 원하는 컬럼 값만 가져옴

1: FROM 참조할 테이블명

2: WHERE 컬럼명 | 함수식 비교 연산자 비교값

3: GROUP BY 그룹을 묶을 컬럼명

4: HAVING 그룹 함수식 비교 연산자 비교값

5: ORDER BY 컬럼명 | 별칭 | 컬럼순법 정렬방식 [NULLS FIRSH | LAST];

[GROUP BY 컬럼명 | 함수식]

여러개의 값을 묶어서 하나로 처리할 목적으로 사용함

그룹으로 묶은 값에 대해서 SELECT절에서 그룹 함수를 사용함

SELECT DEPT_CODE, SUM(SALARY)

FROM EMPLOYEE; >> 에러 발생

그룹 함수는 단 한개의 결과 값만 산출하므로 그룹이 여러개일 경우 오류 발생

- 여러개의 결과 값을 산출하기 위해 그룹 함수가 적용된 그룹의 기준을 GROUP BY절에 기술하여 사용

SELECT DEPT_CODE, SUM(SALARY) FROM EMPLOYEE GROUP BY DEPT_CODE;

부서코드, 그룹별 급여 합계, 그룹별 급여 평균(정수처리), 인원 수 조회 후 부서코드 순으로 정렬

SELECT DEPT_CODE 부서코드, SUM(SALARY) 합계, FLOOR(AVG(SALARY)) 평균, COUNT(*) 인원 수

GROUP BY DEPT_CODE >> 그룹처리

ORDER BY DEPT_CODE; >> 부서코드 순으로 정렬

- 부서코드와 부서별 보너스 받는 사원 수 조회 후 부서코드 순으로 정렬

SELECT DEPT_CODE 부서코드, COUNT(BONUS) 인원수 FROM EMPLOYEE GROUP BY DEPT_CODE ORDER BY DEPT_CODE;

- 직원 테이블에서 직급 코드별, 보너스를 받는 사원의 수를 조회하여 직급 코드순 오름차순 정렬

단, 보너스 받는 사원이 해당 직급코드에 없다면 조회하지 X

SELECT JOB_CODE 부서코드, COUNT(BONUS) 인원수 FROM EMPLOYEE WHERE BONUS IS NOT NULL >> 사원이 0인 직급 코드 삭제 GROUP BY JOB_CODE ORDER BY JOB_CODE; >> 원하는 조건을 충족하는 ROW를 WHERE절에서 선행적으로 거름

- 성별과 성별별 급여 평균(정수 처리), 급여 합계, 인원 수 조회 후 인원 수 내림차순 정렬

SELECT DECODE(SUBSTR(EMP_NO, 8, 1), 1, '남', 2, '여') 성별, FLOOR(AVG(SALARY) 평균, SUM(SALARY) 합계, COUNT(*) 인원수 FROM EMPLOYEE GROUP BY DECODE(SUBSTR(EMP_NO, 8, 1), 1, '남', 2, '여') ORDER BY COUNT(*) DESC; >> 함수식으로 GROUP BY 가능 * DECODE: 비교하고자 하는 값 또는 컬럼이 조건와 같으면 결과 값 반환 * FLOOR: 내림처리

- 부서별로 같은 직급인 사원의 급여 합계를 조회하고 부서 코드 순으로 정렬

SELECT DEPT_CODE, JOB_CODE, SUM(SALARY) FROM EMPLOYEE GROUP BY DEPT_CODE, JOB_CODE ORDER BY 1; >> 여러 컬럼으로 GROUP BY 가능

[HAVING]

HAVING절: 그룹 함수로 구해올 그룹에 대해 조건을 설정할 때 사용

HAVING 컬럼명 | 함수식 비교 연산자 비교값

- 급여 3,000,000 이상인 직원들의 부서 그룹별 급여 평균 조회(부서 코드 순 정렬)

SELECT DEPT_CODE, FLOOR(AVG(SALARY)) 평균 FROM EMPLOYEEM WHERE SALARY >= 3000000 GROUP BY DEPT_CODE ORDER BY 1;

- 부서 그룹별 급여 평균이 3,000,000 이상인 그룹 조회(부서 코드순 정렬)

;

SELECT DEPT_CODE, FLOOR(AVG(SALARY)) 평균 FROM EMPLOYEE HAVING FLOOR(AVG(SALARY)) >= 3000000 GROUP BY DEPT_CODE ORDER BY 1

- 부서별 그룹의 급여 합계가 9백만원을 초과하는 부서코드와 급여 합계 조회(부서 코드순 정렬)

SELECT DEPT_CODE, SUM(SALARY) FROM EMPLOYEE HAVING SUM(SALARY) > 9000000 GROUP BY DEPT_CODE ORDER BY 1;

※참고

- 급여 합계가 가장 많은 부서의 부서 코드와 부서 합계를 구하세요. (서브쿼리 이용)

SELECT DEPT_CODE, SUM(SALARY) FROM EMPLOYEE GROUP BY DEPT_CODE HAVING SUM(SALARY) = (SELECT MAX(SUM(SALARY)) FROM EMPLOYEE GROUP BY DEPT_CODE); >> 메인 쿼리를 보조하는 서브쿼리 구문

[집계함수 (ROLLUP, CUBE]

그룹별 산출한 결과 값의 집계를 계산하는 함수

- 직급 코드별 급여 합계와 마지막 행에 전체 급여 총합 조회 (직급 코드순 정렬)

SELECT JOB_CODE, SUM(SALARY) FROM EMPLOYEE GROUP BY JOB_CODE ORDER BY 1; >> 각 직급별 급여의 합만 출력 SELECT JOB_CODE, SUM(SALARY) FROM EMPLOYEE GROUP BY ROLLUP(JOB_CODE) ORDER BY 1; >> 마지막 행에 직급별 급여 합을 모두 더한 총합이 출력됨 SELECT JOB_CODE, SUM(SALARY) FROM EMPLOYEE GROUP BY CUBE(JOB_CODE) ORDER BY 1;

ROLLUP과 CUBE를 사용했을 때 같은 결과가 출력된다.

ROLLUP과 CUBE의 차이점은?

ROLLUP 함수

- 그룹별로 중간 집계 처리를 하는 함수

- GROUP BY절에서만 사용하는 함수

- 그룹별로 묶여진 값에 대한 중간 집계와 총 집계를 구할 때 사용

- 그룹 함수로 계산된 결과 값들에 대한 총 집계가 자동으로 추가

* 인자로 전달받은 그룹 중 '가장 먼저' 지정한 그룹별 합계와 총 합계를 구하는 함수

- 부서 코드마다 직급 코드별 급여의 합, 부서별 급여의 합, 총합 조회(부서 코드순 정렬)

SELECT DEPT_CODE, JOB_CODE, SUM(SALARY) FROM EMPLOYEE GROUP BY ROLLUP(DEPT_CODE, JOB_CODE) << 첫 번째 행에 대한 그룹별 합계 ORDER BY 1;

CUBE 함수

* 그룹으로 지정된 모든 그룹에 대한 집계와 총 합계를 구하는 함수

SELECT DEPT_CODE, JOB_CODE, SUM(SALARY) FROM EMPLOYEE GROUP CUBE (DEPT_CODE, JOB_CODE) << 모든 행에 대한 그룹별 합계가 출력됨 ORDER BY 1;

GROUPING 함수

- ROLLUP이나 CUBE에 의한 산출물이 인자로 전달 받은 컬럼 집합의 산출물이면 0을 반환하고 아니면 1을 반환하는 함수

SELECT DEPT_CODE, JOB_CODE, SUM(SALARY), GROUPING(DEPT_CODE) "부서별그룹묶인상태", GROUPING(JOB_CODE) "직급별그룹묶인상태" FROM EMPLOYEE GROUP BY ROLLUP(DEPT_CODE, JOB_CODE) ORDER BY DEPT_CODE; SELECT DEPT_CODE, JOB_CODE, SUM(SALARY), CASE WHEN GROUPING(DEPT_CODE) = 0 AND GROUPING(JOB_CODE) = 1 THEN '부서별합계' WHEN GROUPING(DEPT_CODE) = 1 AND GROUPING(JOB_CODE) = 0 THEN '직급별합계' WHEN GROUPING(DEPT_CODE) = 0 AND GROUPING(JOB_CODE) = 0 THEN '그룹별합계' ELSE '총합계' END 구분 FROM EMPLOYEE GROUP BY CUBE(DEPT_CODE, JOB_CODE) ORDER BY 1;

SET OPERATION

- 여러가지 조건이 있을 때 그에 해당하는 여러개의 결과 값을 결합시키고 싶을 때 사용

UNION은 OR 같은 개념(합집합)

INTERSECT는 AND 같은 개념(교집합)

UNION ALL은 OR 결과 값에서 AND 결과값이 더해진 것 (합집함 + 교집함)

MINUS는 차집함

UNION

- 여러개의 쿼리 결과를 하나로 합치는 연산자. 중복된 영역을 제외하여 하나로 합친다.

SELECT EMP_ID, EMP_NAME, DEPT_CODE, SALARY FROM EMPLOYEE WHERE DEPT_CODE = 'D5' UNION SELECT EMP_ID, EMP_NAME, DEPT_CODE, SALARY FROM EMPLOYEE WHERE SALARY > 3000000; >> 위 쿼리문의 결과는 아래처럼 WHERE절에 OR을 쓴 것과 같다. SELECT EMP_ID, EMP_NAME, DPET_CODE, SALARY FROM EMPLOYEE WHERE DEPT_CODE = 'D5' OR SALARY > 3000000;

INTERSECT

- 여러개의 SELECT한 결과에서 공통 부분만 결과로 추출(교집합)

SELECT EMP_ID, EMP_NAME, DEPT_CODE, SALARY FROM EMPLOYEE WHERE DEPT_CODE = 'D5' INTERSECT SELECT EMP_ID, EMP_NAME, DEPT_CODE, SALARY FROM EMPLOYEE WHERE SALARY > 3000000; >> 위 쿼리문의 결과는 아래처럼 WHERE절에 AND를 쓴 것과 같다. SELECT EMP_ID, EMP_NAME, DEPT_CODE, SALARY FROM EMPLOYEE WHERE DEPT_CODE = 'D5' AND SALARY > 3000000;

UNION ALL

- 여러개의 쿼리 결과를 하나로 합치는 연산자

- UINON과의 차이점은 중복 영역을 모두 포함시키는 것(합집함 + 교집함)

SELECT EMP_ID, EMP_NAME, DEPT_CODE, SALARY FROM EMPLOYEE WHERE DEPT_CODE = 'D5' UNION ALL SELECT EMP_ID, EMP_NAME, DEPT_CODE, SALARY FROM EMPLOYEE WHERE SALARY > 3000000;

MINUS

- 선행 SELECT 결과에서 다음 SELECT 결과와 겹치는 부분을 제외한 나머지 부분만 추출(차집합)

- 부서 코드 D5 중 급여가 300만을 초과하는 직원 제외

SELECT EMP_ID, EMP_NAME, DEPT_CODE, SALARY FROM EMPLOYEE WHERE DEPT_CODE = 'D5' MINUS SELECT EMP_ID, EMP_NAME, DEPT_CODE, SALARY FROM EMPLOYEE WHERE SALARY > 3000000; >> 위 쿼리문의 결과는 다음과 같다. >> 부서코드 D5 중 급여가 300만 이하인 직원 조회 SELECT EMP_ID, EMP_NAME, DEPT_CODE, SALARY FROM EMPLOYEE WHERE DPET_CODE = 'D5' AND SALARY <= 3000000;

GROUPING SETS

- 그룹별로 처리된 여러개 SELECT문을 하나로 합칠 때 사용

- SET OPERATION를 사용한 결과와 동일

SELECT DEPT_CODE, JOB_CODE, MANAGER_ID, COUNT(*), FLOOR(AVG(SALARY)) FROM EMPLOYEE GROUP BY GROUPING SETS((DEPT_CODE, MANAGER_ID), << 1부터 14행까지 (JOB_CODE, MANAGER)ID)) << 15행부터 ORDER BY 1;

Toplist

최신 우편물

태그