개발하는 삶

[Oracle] join 본문

CS/Database

[Oracle] join

삶_ 2022. 8. 11. 12:49

 

테이블 join

  • 두개 이상의 테이블을 연결하여(=) 하나의 테이블처럼 출력할 때 사용
  • 등가 조인 
    • *(아래는 예시)
    • SELECT 테이블1.컬럼 ,  테이블2.컬럼 ... (선택할 테이블의 필드들)
    • FROM 테이블1, 테이블2  (사용할 테이블들)
    • WHERE 조인조건 (ex. 테이블1별칭.id = 테이블2별칭.id ) ('=' 을 조건으로 하는 조인)
    • AND 일반조건
      • from절에 테이블 별명을 사용할 경우, SQL문 전체에 별명으로 사용해야 함
  • 비등가 조인
    • 부등호가 포함된 조인조건을 이용하는 조인 (조인 조건에 '=' 이 없는 경우)
  • 자체 조인
    • 자기 참조를 하여, 동일 테이블 간의 조인 방법을 사용하는 것
    • *(아래는 예시)
    • SELECT 별명1.컬럼, 별명2.컬럼, ...
    • FROM 테이블 별명1, 테이블 별명2, ...
    • WHERE 조인 조건
    • AND 일반 조건
  • 외부 조인
    • 보여주고 싶은쪽에 (+)을 이용
    • 두 테이블 간 조인 실행 시, 어느 한쪽의 열이 null이어도 강제로 출력하는 방식
-- from절에 여러 테이블 선언하기 (테이블을 하나인것처럼 합침)
-- 중복의 문제가 생김
SELECT *
FROM emp, DEPT
ORDER BY EMPNO


-- 테이블의 별칭 생성
SELECT *
FROM emp e1, emp e2;

SELECT *
FROM emp e, SALGRADE s --e,s 는 별칭
WHERE e.sal >= s.losal AND s.hisal <= e.sal

-- 사진 1-1
SELECT e.*, d.*
FROM emp e, dept d
WHERE e.DEPTNO = d.DEPTNO  --e 테이블과 d 테이블 내의 DEPTNO 값이 같은 경우를 한줄로 매치해줌



--외부조인
-- (+) 가 없는 것은 모든 내용을 출력 (null이어도 일단 출력은 함)
-- (+) 가 있는 것은 표시할 내용이 없으면 null로 표시
SELECT e1.empno, e1.ename, e1.MGR, e2.EMPNO, e2.ENAME, e2.MGR 
FROM emp e1, emp e2
WHERE e1.mgr = e2.EMPNO(+)
ORDER BY e1.EMPNO

1-1

 

 

 

 

표준 문법으로 배우는 조인

 

NATURAL JOIN

  • 등가조인 중 하나
  • 두 테이블 간에 컬럼이 동일한 컬럼과 값을 가졌다면, 해당 데이터들 열만이 모두 조회됨
    • 만약 특정 컬럼이 따로 표시되어있지 않은 경우,
    • 둘 중에 공통 컬럼과 값인 부분의 열만 한 테이블로 합쳐 조회됨
  • *(아래는 예시)
    • SELECT 컬럼, 컬럼, ...
    • FROM 테이블1
    • NATURAL JOIN 테이블2
    • [NATURAL JOIN 테이블3] ...
    • WHERE 검색 조건;

 

JOIN ~ USING

  • 자연 조인은 사용하는 테이블들의 동일한 이름, 형식이 두가지 이상인 경우 사용이 불가능 해짐.
  • 자연 조인과는 다르게,
    • 같은 이름을 가진 컬럼들 중에서도 특정 컬럼을 따로 선택할 수 있음
    • 그 컬럼 내의 값이 두 테이블 모두 같은 값을 갖고있을때 불러와짐
  • 따라서 이 조인문을 구사함
  • *(아래는 예시)
    • SELECT 컬럼, 컬럼, ...
    • FROM 테이블1
    • JOIN 테이블2 USING(조인 컬럼)  //테이블2 내에서 조인컬럼이 동일한 것들
    • [JOIN 테이블3 USING(조인 컬럼)] ...
    • WHERE 검색 조건;

 

 

Join ~ on

  • 등가 조인은 using 절, 비등가 조인은 on 절을 이용
  • FROM 테이블명1
  • JOIN 테이블명2 ON (조인 조건식)

 

 

 

join outer

-- 테이블 별로 방향 나누기
-- 왼쪽이 null이더라도 오른쪽은 꼭 출력해달라는 뜻 (dept 테이블이 오른쪽에 있으니 해당됨)
SELECT e.deptno, e.job, d.dname, d.loc
FROM emp e
	right OUTER JOIN dept d ON (e.DEPTNO  = d.DEPTNO)
    
-- 오른쪽이 null이더라도 왼쪽은 꼭 출력해달라는 뜻 
SELECT e.deptno, e.job, d.dname, d.loc
FROM emp e
	left OUTER JOIN dept d ON (e.DEPTNO  = d.DEPTNO)

 

 

총합 예제

-- Q1
-- sal이 2000초과인 사원들의 부서 정보, 사원정보를 출력하자
SELECT d.deptno, d.DNAME , e.empno, e.ename, e.sal
FROM emp e, dept d
WHERE e.sal > 2000
AND e.DEPTNO = d.DEPTNO -- 중복제거
ORDER BYdeptno




-- Q2
-- 부서별 평균 급여, 최대 급여, 최소 급여, 사원수 출력
SELECT
	d.deptno,
	d.dname,
	floor(avg(e.sal)) AS avg_sal,
	max(e.sal) AS avg_sal,
	min(e.sal) AS min_sal,
	count(*) AS cnt
FROM emp e, dept d
WHERE d.DEPTNO <= 30
AND e.DEPTNO = d.DEPTNO -- 중복제거
GROUP BY d.DEPTNO, d.dname
ORDER BY d.DEPTNO 


-- 위랑 같은 결과값
SELECT
	d.deptno,
	d.dname,
	trunc(avg(e.sal)) AS avg_sal,
	max(e.sal) AS avg_sal,
	min(e.sal) AS min_sal,
	count(*) AS cnt
FROM emp e
	LEFT OUTER JOIN dept d ON (e.DEPTNO = d.DEPTNO)
GROUP BY
	d.DEPTNO, d.DNAME
ORDER BY d.DEPTNO




-- Q3
-- 모든 부서, 사원 정보를 부서번호, 사원 이름순으로 정렬하여 출력
SELECT
	d.deptno,
	d.dname,
	e.empno,
	e.ename,
	e.job,
	e.sal
FROM emp e
	right OUTER JOIN dept d ON (e.DEPTNO = d.DEPTNO)
ORDER BY d.deptno, e.ename
	



-- Q4
-- 모든 부서, 사원, 급여 등급, 각 사원의 직속 상관의 정보를
-- 부서 번호, 사원 번호 순서로 정렬
SELECT *
FROM 

SELECT
	d.deptno,
	d.dname,
	e.empno,
	e.ename,
	e.mgr,
	e.sal,
	e.DEPTNO  AS deptno_1,
	s.losal AS losal,
	s.hisal AS hisal,
	s.grade AS grade,
	e2.mgr AS mgr_empno,
	e2.ename AS mgr_ename
FROM dept d
	left OUTER JOIN emp e ON (e.DEPTNO = d.DEPTNO) --중복 제거
	LEFT OUTER JOIN SALGRADE s ON (e.sal >= s.losal AND e.sal < s.hisal)
	LEFT OUTER JOIN emp e2 ON (e.mgr = e2.empno)
ORDER BY d.DEPTNO, e.EMPNO

 

 

 

서브쿼리

  • 어떤 조건에 따라서 변할수있는 데이터의 값을 비교하는 것
-- jones씨와 같은 job을 갖고있는 사람을 모두 출력
-- 단일행
SELECT *
FROM emp
WHERE job = (
	SELECT job
	FROM emp
	WHERE ename='JONES')

	
    
-- 다중행
-- 부서별로 최대 급여 출력
SELECT max(sal) FROM emp
GROUP BY DEPTNO



-- in : 메인쿼리의 데이터가 서브쿼리의(in 뒤가 서브쿼리임)
-- 결과 중 하나라도 일치한다면 true
SELECT * FROM EMP
WHERE sal in (SELECT max(sal) FROM emp
	GROUP BY DEPTNO)
	
	
    
-- any, some 연산자
-- 서브쿼리의 결과가 둘 중 값 하나만 조건식에 맞아 떨어지면 출력 대상이 됨
SELECT * FROM EMP
WHERE sal > any (SELECT max(sal) FROM emp
	GROUP BY DEPTNO)


-- with절로 서브쿼리 만들기
-- 별칭으로 저장후 씀
WITH e10 AS (
	SELECT * FROM emp WHERE deptno = 10)
SELECT *
FROM
	e10,
	dept d
WHERE e10.deptno = d.DEPTNO 
	



-- emp의 모든 사원을 대상으로
-- 한명당 그 한명에 해당하는 부서의 최소 급여와 비교
SELECT *
FROM emp e1
WHERE sal > (
	SELECT min(sal)
	FROM emp e2
	WHERE e2.DEPTNO = e1.DEPTNO)
ORDER BY DEPTNO, sal;



-- select 안의 select 문 넣기
SELECT
	empno,
	deptno,
	(SELECT dname FROM dept d
	WHERE d.deptno = e.DEPTNO) sub_dname
FROM emp e

 

 

 

 

출처&참고

https://keep-cool.tistory.com/41

'CS > Database' 카테고리의 다른 글

[Oracle] create, alter 등  (0) 2022.08.16
[MyBatis] 기본 지식  (0) 2022.08.12
[Oracle] to_date, to_char  (0) 2022.08.10
[Oracle] 자료형  (0) 2022.08.09
[Oracle] 데이터 형식  (0) 2022.08.01