Non EQUI(비등가) JOIN은 두 개의 테이블 간에 칼럼 값들이 서로 정확하게 일치하지 않는 경우에 사용된다. Non EQUI JOIN의 경우에는 “=” 연산자가 아닌 다른(Between, >, >=, <, <= 등) 연산자들을 사용하여 JOIN을 수행하는 것이다. 두 개의 테이블이 PK-FK로 연관관계를 가지거나 논리적으로 같은 값이 존재하는 경우에는 “=” 연산자를 이용하여 EQUI JOIN을 사용한다. 그러나 두 개의 테이블 간에 칼럼 값들이 서로 정확하게 일치하지 않는 경우에는 EQUI JOIN을 사용할 수 없다. 이런 경우 Non EQUI JOIN을 시도할 수 있으나 데이터 모델에 따라서 Non EQUI JOIN이 불가능한 경우도 있다.
Non EQUI 조인을 위해 테이블 생성과 값을 입력해보자.
1) EMP 사원 테이블 생성
CREATE TABLE "EMP"
( "ENAME" VARCHAR2(10 BYTE),
"DEPTNO" VARCHAR2(10 BYTE),
"HIREDATE" DATE,
"SAL" NUMBER,
"MGR" VARCHAR2(10 BYTE)
)
Insert into EMPSET (ENAME,DEPTNO,HIREDATE,SAL,MGR) values ('유재석','1001',to_date('19/06/07','RR/MM/DD'),3000000,'0011');
Insert into EMPSET (ENAME,DEPTNO,HIREDATE,SAL,MGR) values ('이휘재','1001',to_date('19/02/04','RR/MM/DD'),550000,'2233');
Insert into EMPSET (ENAME,DEPTNO,HIREDATE,SAL,MGR) values ('박명수','1001',to_date('19/01/22','RR/MM/DD'),6000000,'2233');
Insert into EMPSET (ENAME,DEPTNO,HIREDATE,SAL,MGR) values ('강호동','1001',to_date('16/04/14','RR/MM/DD'),7000000,'7788');
Insert into EMPSET (ENAME,DEPTNO,HIREDATE,SAL,MGR) values ('하동훈','1001',to_date('18/01/22','RR/MM/DD'),1956000,'7788');
Insert into EMPSET (ENAME,DEPTNO,HIREDATE,SAL,MGR) values ('노홍철','1001',to_date('18/08/28','RR/MM/DD'),1652000,'2233');
Insert into EMPSET (ENAME,DEPTNO,HIREDATE,SAL,MGR) values ('길',
'1001',to_date('17/07/24','RR/MM/DD'),1564000,'0011');
Insert into EMPSET (ENAME,DEPTNO,HIREDATE,SAL,MGR) values ('정형돈','1001',to_date('11/01/21','RR/MM/DD'),1686000,'7788');
Insert into EMPSET (ENAME,DEPTNO,HIREDATE,SAL,MGR) values ('정준하','1001',to_date('12/02/12','RR/MM/DD'),6910000,'0011');
Insert into EMPSET (ENAME,DEPTNO,HIREDATE,SAL,MGR) values ('김제동','1001',to_date('13/11/13','RR/MM/DD'),5100000,'0011');
Insert into EMPSET (ENAME,DEPTNO,HIREDATE,SAL,MGR) values ('이경규','1001',to_date('14/10/10','RR/MM/DD'),3150000,'7788');
Insert into EMPSET (ENAME,DEPTNO,HIREDATE,SAL,MGR) values ('은지원','1001',to_date('19/04/14','RR/MM/DD'),4150000,'7788');
Insert into EMPSET (ENAME,DEPTNO,HIREDATE,SAL,MGR) values ('장성규','1004',to_date('19/05/25','RR/MM/DD'),8131000,'2233');
Insert into EMPSET (ENAME,DEPTNO,HIREDATE,SAL,MGR) values ('이수근','1002',to_date('19/08/08','RR/MM/DD'),5110300,'8899');
Insert into EMPSET (ENAME,DEPTNO,HIREDATE,SAL,MGR) values ('이효리','1002',to_date('19/09/14','RR/MM/DD'),6102100,'8899');
Insert into EMPSET (ENAME,DEPTNO,HIREDATE,SAL,MGR) values ('이상순','1002',to_date('13/12/12','RR/MM/DD'),2345000,'8899');
Insert into EMPSET (ENAME,DEPTNO,HIREDATE,SAL,MGR) values ('아이유','1002',to_date('11/11/22','RR/MM/DD'),2351100,'2233');
Insert into EMPSET (ENAME,DEPTNO,HIREDATE,SAL,MGR) values ('박준형','1002',to_date('15/05/21','RR/MM/DD'),1681000,'8899');
Insert into EMPSET (ENAME,DEPTNO,HIREDATE,SAL,MGR) values ('김태우','1002',to_date('16/06/26','RR/MM/DD'),2360000,'8899');
Insert into EMPSET (ENAME,DEPTNO,HIREDATE,SAL,MGR) values ('데니안','1004',to_date('11/10/04','RR/MM/DD'),9042000,'2233');
Insert into EMPSET (ENAME,DEPTNO,HIREDATE,SAL,MGR) values ('손호영','1003',to_date('17/07/27','RR/MM/DD'),5141000,'8899');
Insert into EMPSET (ENAME,DEPTNO,HIREDATE,SAL,MGR) values ('데프콘','1003',to_date('19/07/24','RR/MM/DD'),5410000,'0011');
Insert into EMPSET (ENAME,DEPTNO,HIREDATE,SAL,MGR) values ('김태호','1003',to_date('19/02/24','RR/MM/DD'),3211000,'0011');
Insert into EMPSET (ENAME,DEPTNO,HIREDATE,SAL,MGR) values ('양세형','1003',to_date('19/03/24','RR/MM/DD'),2130000,'0011');
Insert into EMPSET (ENAME,DEPTNO,HIREDATE,SAL,MGR) values ('조세호','1002',to_date('19/01/24','RR/MM/DD'),5050000,'8899');
Insert into EMPSET (ENAME,DEPTNO,HIREDATE,SAL,MGR) values ('유병재','1004',to_date('19/02/24','RR/MM/DD'),6200000,'7788');
Insert into EMPSET (ENAME,DEPTNO,HIREDATE,SAL,MGR) values ('박수홍','1002',to_date('19/12/24','RR/MM/DD'),2130000,'7788');
Insert into EMPSET (ENAME,DEPTNO,HIREDATE,SAL,MGR) values ('조용필','1001',to_date('19/06/24','RR/MM/DD'),null,'7788');
2) SALGRADE 월급 등급 테이블 생성
CREATE TABLE "SALGRADE"
( "GRADE" CHAR(1 BYTE),
"LOSAL" NUMBER,
"HISAL" NUMBER
)
Insert into SALGRADE (GRADE,LOSAL,HISAL) values ('1',500000,700000);
Insert into SALGRADE (GRADE,LOSAL,HISAL) values ('2',700001,1500000);
Insert into SALGRADE (GRADE,LOSAL,HISAL) values ('3',1500001,2500000);
Insert into SALGRADE (GRADE,LOSAL,HISAL) values ('4',2500001,5000000);
Insert into SALGRADE (GRADE,LOSAL,HISAL) values ('5',5000001,8000000);
Insert into SALGRADE (GRADE,LOSAL,HISAL) values ('6',8000001,10000000);
테이블 컬럼 값을 확인해보면 알겠지만 EQUI JOIN과는 다르게 동일한 칼럼값이 두 개의 테이블에서 존재하지 않는다. 이렇게 동일한 칼럼값이 없는 테이블에는 EQUI JOIN이 아닌 Non-EQUI JOIN문을 사용해야한다.
이제 테이블을 생성 하였으니 Non-EQUI JOIN문을 실행시켜보자.
질문은 다음과 같다. 먼저 질문에 해당하는 쿼리문을 고민해보고 답을 확인하는 것을 추천한다.
어떤 사원이 받고 있는 급여가 어느 등급에 속하는 등급인지 알아보자.
SELECT E.ENAME, E.SAL, S.GRADE FROM EMP E, SALGRADE S WHERE E.SAL BETWEEN S.LOSAL AND S.HISAL;
다음 쿼리문과 같이 Non-EQUI JOIN은 BETWEEN이나 부등호 수식이 들어간 JOIN문을 Non-EQUI JOIN이라고 할 수 있다.
사원(EMP) 테이블에서 사원들의 급여가 급여등급(SALGRADE) 테이블의 등급으로 표시되기 위해서는 “=” 연산자로 JOIN을 이용할 수가 없다.
참고로 BETWEEN a AND b와 같은 SQL 연산자 뿐만 아니라 “=” 연산자가 아닌 “>”나 “<”와 같은 다른 연산자를 사용했을 경우에도 모두 Non EQUI JOIN에 해당한다. 단지 BETWEEN SQL 연산자가 Non EQUI JOIN을 설명하기 쉽기 때문에 예를 들어 설명한 것에 불과하며, 데이터 모델에 따라서 Non EQUI JOIN이 불가능한 경우도 있다.
'SQL' 카테고리의 다른 글
[SQL] EQUI JOIN (0) | 2019.07.31 |
---|