모든 일상

3일차 본문

코딩 공부/SQL

3일차

통통푸린 2021. 5. 3. 08:31
728x90
반응형

다중행 함수
-> 그룹함수, 통계함수
-> 여러행의 값 => 처리 => 하나의 값을 반환
-> sum, avg, count, mas, min..........등
-> null 값은 통계에서 제외한다.

count( ) 함수
- ( * ) : row의 수를 카운트한다.
- ( 컬럼명 ) 

--총사원수에서 커미션 수당을 받는 사원과 안받는 사원
select count(*) as "총사원수", count(commission_pct) as "수당을 받는 사원수",
        count(*) - count(commission_pct) as " 받지 않는  사원수 "
from emp;

--null값을 제외하여 커미션 수당을 받는사람을 검색
select count(*) as "수당을 받는 사람"
from emp 
where commission_pct is not null;

--최고급여와 최저급여
select max(salary), min(salary)
from emp;

--15000이상 받는 사원의 수
select count(*) as "고액연봉자 수"
from emp
where salary >= 15000;

그룹
- group by 컬럼명, 컬럼명 (컬럼명, 뒤이 컬럼명을 넣게 되면 컬럼안에 도 그룹을 만들게된다.)
- select 절에 그룹함수 이외의 컬럼or 수식 등을 group by 절에 기술을 해야함~!(하지않으면 오류가 발생)

-- 부서를 그룹, 부서별 오름차순 정렬
select department_id, max(salary), min(salary)
from emp
group by department_id
order by department_id;

--년도별 입사 인원수
select to_char(hire_date,'yyyy') as"입사년도", count(*) as " 입사 인원수 "
from emp
group by to_char(hire_date,'yyyy')
order by 1;

--부서별, 직군
select department_id, job_id, max(salary), min(salary)
from emp
group by department_id, job_id
order by 1,2 ;

--부서별 평균급여
select department_id , round(avg(salary),0)
from emp
group by department_id
order by department_id;

having 절
- 그룹을 제한
- 원하는 그룹만 표시
- where 절 과 유사
- having 조건식 and 조건식 or 조건식
- group by 절이 있는 경우만 사용이 가능하다.
- select 절에 컬럼별칭을 사용할 수 없다. 

--부서별 평균급여 단, 평균급여 8000이상인 부서만 출력
select department_id, round(avg(salary),0) as 부서평균급여
from emp
group by department_id
having round(avg(salary),0) >= 8000
order by 부서평균급여;

ex) 구매( 구매번호, 구매자, 상품번호, 상품갯수, 구매금액합계, 구매날짜)- 가정 2021년 정보만 존재
1. 구매금액의 합계가 500000 이상인 구매자 명단

select 구매자, sum(구매금액합계) as "총 구매금액"
from 구매
group by 구매자
having sum(구매금액합계) >= 500000
order by 2 desc;

2. 지난달 100개 이상 팔린 상품번호
select 상품번호, sum(상품개수) as "총 팔린개수"
from 구매
where to_char(구매날짜, 'mm') = to_char(sysdate,'mm')-1
group by 상품번호
having sum(삼품개수) >= 100
order by 2 desc;

ex) 고객( 고객번호, 고객명, 생일 , 성별 .......)

1. 고객 연령별 인원수 
힌트) 나이를 구한다 - 연령대를 구한다 - 연령병 인원 수를 구한다.

나이 : to_char(sysdate, 'yyyy') - to_char(생일, 'yyyy') +1 => 27이라하면
연령대 27 -> 20대 :trunc(to_char(sysdate, 'yyyy')-to_char(생일, 'yyyy') + 1, -1) => 20대

select trunc(to_char(sysdate, 'yyyy')-to_char(생일, 'yyyy') + 1, -1) as 연령대, count(*) as 인원수
from 고객
group by trunc(to_char(sysdate, 'yyyy')-to_char(생일, 'yyyy') + 1, -1)
order by 1;

연령대 인원수, 비율
select trunc(to_char(sysdate, 'yyyy')-to_char(생일, 'yyyy') + 1, -1) as 연령대,
        count(*) as 인원수,
        trunc(count(*) / (select count (*) from 고객, 1) as 비율
from 고객
group by trunc(to_char(sysdate, 'yyyy')-to_char(생일, 'yyyy') + 1, -1)
order by 1;

## JOIN
- 테이블을 옆으로 합치는 것이다.
- 공통된 컬럼을 조인
- oracle 전영 구문, ansi 표준 구문 모두 가능

## 조인의 종류
1. cross join
- 조인조건 없음
- 모둔 경우의 수 조회 = 조인테이블명2.컬럼명
2. equi join
3. non-equi join
4. outer join
5. self join

select employee_id, last_name, department_name
from emp, dept -> cross조인 조건없이 모두 연결을 하기때문에 오버플로가 발생 할 수있고, 비효율적이다.

데이터가 너무 많다.

##oracle 구문
## eqio join

-- 사번, 이름, 부서명 원하는 정보만 (오라클 구문)
select employee_id, last_name, department_name
from emp, dept
where emp.department_id = dept.department_id;

-- 한정자표시법을 사용하여 보다 효과적이다. (테이블의 별칭 사용시 as 쓰면 안된다. 오류가 발생)
select e.employee_id, e.last_name, d.department_name
from emp e, dept d
where e.department_id = d.department_id;

## 표준 구문 
- join조건을 from 절에 기술

## equi join

-- 사번, 이름, 부서명 원하는 정보만( 두 테이블에 동일한 컬럼이 있는 경우 )
select employee_id, last_name, department_name
from emp e join dept d using(department_id);

-- 두 테이블에 동일한 이름의 컬럼이 아닌경우
select employee_id, last_name, department_name
from emp e join dept d on (e.department_id = d.department_id);

##orcle 구문

## outer join
- left outer join - 실무적으로 많이 쓰임
- right outer join 
- full outer join 지원 X

## left outer join 
-- 정보가 없으면 null로 채워서 나온다.
select e.employee_id, e.last_name, d.department_name
from emp e, dept d
where e.department_id = d.department_id (+) ; -> 오라클 구문

select employee_id, last_name, department_name
from emp e left outer join dept d using(department_id); -> 표준 구문

## right outer join 
-- 정보가 없으면 null로 채워서 나온다.
select e.employee_id, e.last_name, d.department_name
from emp e, dept d
where e.department_id(+) = d.department_id; -> 오라클 구문

select employee_id, last_name, department_name
from emp e right outer join dept d using(department_id); -> 표준 구문

##표준 구문
- left outer join 
- right outer join 
- full outer join
- outer 생략가능


## full outer join 

select employee_id, last_name, department_name
from emp e full outer join dept d using(department_id);

## 여러테이블 조인

ex)
테이블 : a, b, c
select *
from a,b,c
where a.aa = b.bb and b.bb=c.cc;

select *
from (a join b using(aa)) join c on (b.bb=c.cc)

## self join

--사번, 사원이름, 상관이름
select e.employee_id as 사번, e.last_name as 사원이름, m.last_name as 상관이름
from emp e, emp m
where e.manager_id = m.employee_id

## non equi join 

--이름, 월급, 월급레벨
select e.last_name, e.salary, j.GRADE_LEVEL
from emp e, JOB_GRADES j
where e.salary between j.lowest_sal and j.highest_sal ;

728x90
반응형

'코딩 공부 > SQL' 카테고리의 다른 글

SQLD 합격 후기 및 공부법  (1) 2024.06.14
SQL JOIN 예제문제  (0) 2021.04.30
3일차 예제문제  (0) 2021.04.30
2일차 예제문제  (0) 2021.04.30
1일차 예제문제  (0) 2021.04.28