SQL Cook: 3. 7장 두 테이블에 같은 데이터가 있는지 확인하기(Oracle)

0

SQL_COOK

목록 보기
16/35
post-thumbnail

3. 7장 두 테이블에 같은 데이터가 있는지 확인하기

Q. 두 테이블 또는 뷰에 같은 데이터(카디널리티 - cardinality - 및 값)가 있는지 알고 싶다

create view v_card
as
select * from emp where deptno != 10
union all
select * from emp where ename = 'WARD'

>>
EMPNO	ENAME	JOB			MGR		HIREDATE	SAL		COMM	DEPTNO
7839	KING	PRESIDENT	 - 		17-NOV-81	5000	 - 		10
7698	BLAKE	MANAGER		7839	01-MAY-81	2850	 - 		30
7782	CLARK	MANAGER		7839	09-JUN-81	2450	 - 		10
7566	JONES	MANAGER		7839	02-APR-81	2975	 - 		20
7788	SCOTT	ANALYST		7566	19-APR-87	3000	 - 		20
7902	FORD	ANALYST		7566	03-DEC-81	3000	 - 		20
7369	SMITH	CLERK		7902	17-DEC-80	800	 	 - 		20
7499	ALLEN	SALESMAN	7698	20-FEB-81	1600	300		30
7521	WARD	SALESMAN	7698	22-FEB-81	1250	500		30
7654	MARTIN	SALESMAN	7698	28-SEP-81	1250	1400	30
7844	TURNER	SALESMAN	7698	08-SEP-81	1500	 0		30
7876	ADAMS	CLERK		7788	23-MAY-87	1100	 - 		20
7900	JAMES	CLERK		7698	03-DEC-81	950	 	 - 		30
7934	MILLER	CLERK		7782	23-JAN-82	1300	 - 		10
7521	WARD	SALESMAN	7698	22-FEB-81	1250	500		30

View 'V_CARD' 의 데이터가 'EMP' 테이블과 정확히 같은지를 확인하려고 한다.

쿼리에서도 나왔다시피 사원명이 'WARD'인 행이 복제되어 중복데이터도 표시하고 있다.

View 'V_CARD'와 'EMP' 테이블의 차이는

  • 부서코드가 10인 사원정보 3행이 'V_CARD'는 없다
  • 사원명이 'WARD'인 행이 'V_CARD'에는 중복되어 있다

이에 대해 다음과 같은 결과셋을 반환하려고 한다

EMPNO	ENMAE	JOB			MGR		HIREDATE		SAL		COMM	DEPTNO	CNT
7521	WARD	SALESMAN	7698	22-FEB-2006		1250	500		30		1
7521	WARD	SALESMAN	7698	22-FEB-2006		1250	500		30		2
7782	CLARK	MANAGER		7839	09-JUN-2006		2450			10		1
7521	KING	PRESIDENT	7698	17-NOV-2006		5000			10		1
7521	MILLER	CLERK		7782	23-JAN-2007		1300			10		1

A. 차집합 MINUS 또는 EXCEPT를 수행하는 함수는, 테이블 비교 문제를 비교적 쉽게 해결할 수 있다.

만약 이런 기능을 제공하지 않는다면 상관 서브쿼리를 사용할 수 있다.

case: Oracle

집합 연산 MINUSUNION ALL을 사용하여 View 'V_CARD'에서 'EMP' 테이블과 다른 점을 찾고, 'EMP' 테이블에서 View 'V_CARD'와 다른 점을 찾아서 조합한다.

(
select empno, ename, job, mgr, hiredate, sal, comm, deptno, count(*) as cnt from v_card
	group by empno, ename, job, mgr, hiredate, sal, comm, deptno
    minus
select empno, ename, job, mgr, hiredate, sal, comm, deptno, count(*) as cnt from emp
	group by empno, ename, job, mgr, hiredate, sal, comm, deptno
)
	union all
(
select empno, ename, job, mgr, hiredate, sal, comm, deptno, count(*) as cnt from emp
	group by empno, ename, job, mgr, hiredate, sal, comm, deptno
    minus
select empno, ename, job, mgr, hiredate, sal, comm, deptno, count(*) as cnt from v_card
	group by empno, ename, job, mgr, hiredate, sal, comm, deptno
)
	

아주 우직하게 서로 다른 점을 찾아서 UNION ALL을 실행한 쿼리다.

짚고 넘어가기: GROUP BY

GROUP BY는 같은 값을 가진 행끼리 하나의 그룹으로 뭉쳐준다.

  • 특정 칼럼을 기준으로 GROUP BY를 실행했을 때, 해당 칼럼이 아닌 나머지 칼럼의 값이 제각각이라면 다른 칼럼들을 조회할 수 없다
  • 따라서 GROUP BY의 대상이 되는 칼럼이 아닌, 나머지 칼럼을 SELECT절에서 조회하려고 할 때 주의가 필요하다

다음 포스팅에서 이 문제에 대한 해법을 Maria에서 찾아보도록 하겠다

0개의 댓글