-
Oracle(2022.02.25)2-집합 연산자데이터베이스 2022. 2. 25. 17:43728x90
집합연산자
-합집합(UNION, UNION ALL),교집합(INTERSECT), 차집합(MINUS)결과를 반환하는 연산자
-집합연산자의 대상은 SELECT문의 결과이다.
-조인 등의 복잡한 연산을 줄일 수 있다.
-모든 SELECT문의 컬럼의 수, 데이터타입, 순서가 일치해야함
-첫 SELECT문에 적용된 컬럼타입,이름이 기준이 됨
-CLOB,BLOB,BFILE 타입은 사용 불가
-ORDER BY 절은 맨 마지막 SELECT문에만 사용 가능
1.UNION, UNION ALL (외부조인에 해당)
-합집합의 결과를 교집합 부분의 중복없이(UNION), 중복하여(UNION ALL) 반환한다..첫번째 SELECT문의 결과와 나머지 SELECT문의 결과가 결합하여 반환
(사용형식) SELECT 컬럼 list1 FROM 테이블명 [WHERE 조건] UNION|UNION ALL|INTERSECT|MINUS SELECT 컬럼 list2 FROM 테이블명 [WHERE 조건] UNION|UNION ALL|INTERSECT|MINUS : SELECT 컬럼 listn FROM 테이블명 [WHERE 조건] [ORDER BY 컬럼명];
사용예) 장바구니테이블에서 2005년 5월과 7월에 구매한 모든 회원을 조회하시오.
Alias는 회원번호, 회원명, 주소, 마일리지이다.(집합연산자 사용X) SELECT DISTINCT A.CART_MEMBER AS 회원번호, B.MEM_NAME AS 회원명, B.MEM_ADD1||' '||B.MEM_ADD2 AS 주소, B.MEM_MILEAGE AS 마일리지 FROM CART A, MEMBER B WHERE A.CART_MEMBER=B.MEM_ID AND SUBSTR(CART_NO,1,6) IN('200505','200507') ORDER BY 1;
(집합연산자 UNION 사용O) 20명 11명 합치니까 23명 8명 겹침 SELECT DISTINCT A.CART_MEMBER AS 회원번호, B.MEM_NAME AS 회원명, B.MEM_ADD1||' '||B.MEM_ADD2 AS 주소, B.MEM_MILEAGE AS 마일리지 FROM CART A, MEMBER B WHERE A.CART_MEMBER=B.MEM_ID AND SUBSTR(CART_NO,1,6) ='200505' UNION SELECT DISTINCT A.CART_MEMBER , B.MEM_NAME AS, B.MEM_ADD1||' '||B.MEM_ADD2 , B.MEM_MILEAGE FROM CART A, MEMBER B WHERE A.CART_MEMBER=B.MEM_ID AND SUBSTR(CART_NO,1,6) ='200507' ORDER BY 1;
200505 200507 (집합연산자 UNION ALL 사용O) 31건 반환 8명 중복된거 포함 SELECT DISTINCT A.CART_MEMBER AS 회원번호, B.MEM_NAME AS 회원명, B.MEM_ADD1||' '||B.MEM_ADD2 AS 주소, B.MEM_MILEAGE AS 마일리지 FROM CART A, MEMBER B WHERE A.CART_MEMBER=B.MEM_ID AND SUBSTR(CART_NO,1,6) ='200505' UNION ALL SELECT DISTINCT A.CART_MEMBER , B.MEM_NAME AS, B.MEM_ADD1||' '||B.MEM_ADD2 , B.MEM_MILEAGE FROM CART A, MEMBER B WHERE A.CART_MEMBER=B.MEM_ID AND SUBSTR(CART_NO,1,6) ='200507' ORDER BY 1;
사용예) 2005년 2월과 6월 매입된 상품을 모두 조회하시오.
Alias는 상품코드, 상품명
(집합연산자 사용X) SELECT DISTINCT A.BUY_PROD AS 상품코드, B.PROD_NAME AS 상품명 FROM BUYPROD A,PROD B WHERE A.BUY_DATE BETWEEN TO_DATE('20050201') AND LAST_DAY(TO_DATE('20050201')) AND A.BUY_PROD=B.PROD_ID SELECT DISTINCT A.BUY_PROD AS 상품코드, B.PROD_NAME AS 상품명 FROM BUYPROD A,PROD B WHERE A.BUY_DATE BETWEEN TO_DATE('20050601') AND LAST_DAY(TO_DATE('20050601')) AND A.BUY_PROD=B.PROD_ID;
2월 데이터 일부 5월 데이터일부 (집합연산자 UNION 사용O) 41가지중 6가지 중복 제외하고 출력 SELECT DISTINCT A.BUY_PROD AS 상품코드, B.PROD_NAME AS 상품명 FROM BUYPROD A,PROD B WHERE A.BUY_DATE BETWEEN TO_DATE('20050201') AND LAST_DAY(TO_DATE('20050201')) AND A.BUY_PROD=B.PROD_ID UNION SELECT DISTINCT A.BUY_PROD AS 상품코드, B.PROD_NAME AS 상품명 FROM BUYPROD A,PROD B WHERE A.BUY_DATE BETWEEN TO_DATE('20050601') AND LAST_DAY(TO_DATE('20050601')) AND A.BUY_PROD=B.PROD_ID ORDER BY 1;
(집합연산자 INTERSECT 사용O) 6가지가 중복된 갯수(2월도 6월도) SELECT DISTINCT A.BUY_PROD AS 상품코드, B.PROD_NAME AS 상품명 FROM BUYPROD A,PROD B WHERE A.BUY_DATE BETWEEN TO_DATE('20050201') AND LAST_DAY(TO_DATE('20050201')) AND A.BUY_PROD=B.PROD_ID INTERSECT SELECT DISTINCT A.BUY_PROD AS 상품코드, B.PROD_NAME AS 상품명 FROM BUYPROD A,PROD B WHERE A.BUY_DATE BETWEEN TO_DATE('20050601') AND LAST_DAY(TO_DATE('20050601')) AND A.BUY_PROD=B.PROD_ID ORDER BY 1;
2.INTERSECT
-교집합의 결과를 반환사용예) 사원테이블과 직무변동테이블(JOB_HISTORY)에서 사원번호와
직책코드가 같은 사원을 조회하시오(집합연산자 사용 X) SELECT A.EMPLOYEE_ID AS 사원번호, A.EMP_NAME AS 사원명, A.JOB_ID AS 직책코드 FROM HR.EMPLOYEES A WHERE (A.EMPLOYEE_ID,A.JOB_ID )=ANY (SELECT EMPLOYEE_ID,JOB_ID FROM HR.JOB_HISTORY) (또 다른 코드) SELECT A.EMPLOYEE_ID AS 사원번호, A.EMP_NAME AS 사원명, B.JOB_ID AS 직책코드 FROM HR.EMPLOYEES A,( SELECT EMPLOYEE_ID,JOB_ID FROM HR.JOB_HISTORY)B WHERE A.JOB_ID=B.JOB_ID AND A.EMPLOYEE_ID=B.EMPLOYEE_ID;
쌍으로 비교가 되어야 하는데 앞이 사원번호, 직업번호 순서로 양쪽에서나온 행을 비교해야한다. 하지만 오른쪽은 결과가 10개이므로 관계연산자 '='를 사용X 다중연산자를 사용해야한다.
즉'=': 1명분의 자료 VS 10줄이므로 사용이 안되고 ANY를 써야한다. (확인해보니 IN,=SOME다 가능한듯)
(집합연산자를 사용O) SELECT A.EMPLOYEE_ID AS 사원번호, A.JOB_ID AS 직책코드 FROM HR.EMPLOYEES A INTERSECT SELECT EMPLOYEE_ID, JOB_ID FROM HR.JOB_HISTORY;
(오류 주의- 위에는 3개 밑에는 2개 개수가 맞아야한다.) SELECT A.EMPLOYEE_ID AS 사원번호, A.EMP_NAME AS 사원명, A.JOB_ID AS 직책코드 FROM HR.EMPLOYEES A INTERSECT SELECT EMPLOYEE_ID, JOB_ID FROM HR.JOB_HISTORY;
사용예) 2005년 4월과 5월 6월에 공통으로 판매된 상품을 모두 조회하시오.
Alias는 상품코드, 상품명
사용예) 2005년 4월과 5월 6월에 공통으로 판매된 상품을 모두 조회하시오. Alias는 상품코드, 상품명 (EXISTS 연산자 사용) --2005년 4월에 판매된 상품코드와 상품명 조회 SELECT DISTINCT A.CART_PROD AS 상품코드, B.PROD_NAME AS 상품명 FROM CART A, PROD B WHERE A.CART_PROD=B.PROD_ID AND A.CART_NO LIKE '200504%' --2005년 5월에 판매된 상품코드와 상품명 조회 SELECT DISTINCT CART_PROD AS BID FROM CART WHERE CART_NO LIKE '200505%' --2005년 6월에 판매된 상품코드와 상품명 조회 SELECT DISTINCT CART_PROD AS CID FROM CART WHERE CART_NO LIKE '200506%'
4월 5월 6월 --서브쿼리를 사용한 결합 2005년 6월 판매된 상품코드가 5월 상품코드같은거 참 2005년 5월 상품코드가 2005년 4월상품코드랑 같고 그러면 출력해 SELECT DISTINCT A.CART_PROD AS 상품코드, B.PROD_NAME AS 상품명 FROM CART A, PROD B WHERE A.CART_PROD=B.PROD_ID AND A.CART_NO LIKE '200504%' AND EXISTS ( SELECT 1 FROM CART C WHERE CART_NO LIKE '200505%' AND C.CART_PROD=A.CART_PROD AND EXISTS(SELECT 1 FROM CART D WHERE CART_NO LIKE '200506%' AND D.CART_PROD=C.CART_PROD)) ORDER BY 1;
(집합연산자 INTERSECT 사용) SELECT DISTINCT A.CART_PROD AS 상품코드, B.PROD_NAME AS 상품명 FROM CART A, PROD B WHERE A.CART_PROD=B.PROD_ID AND A.CART_NO LIKE '200504%' INTERSECT SELECT DISTINCT A.CART_PROD, B.PROD_NAME FROM CART A, PROD B WHERE A.CART_PROD=B.PROD_ID AND A.CART_NO LIKE '200505%' INTERSECT SELECT DISTINCT A.CART_PROD, B.PROD_NAME FROM CART A, PROD B WHERE A.CART_PROD=B.PROD_ID AND A.CART_NO LIKE '200506%' ORDER BY 1;
(결합(서브쿼리+집합연산자)) SELECT DISTINCT A.CART_PROD AS 상품코드, B.PROD_NAME AS 상품명 FROM CART A, PROD B WHERE A.CART_PROD=B.PROD_ID AND A.CART_NO LIKE '200504%' AND A.CART_PROD IN ( SELECT DISTINCT CART_PROD FROM CART WHERE CART_NO LIKE '200505%' INTERSECT SELECT DISTINCT CART_PROD FROM CART WHERE CART_NO LIKE '200506%') ORDER BY 1;
3. MINUS(차집합)
- 복수개의 쿼리결과에 대하여 차집합의 결과 반환
사용예)매입테이블에서 2005년 1월과 4월의 매입을 비교하여 1월에만 매입된 상품정보를
출력 하시오(단, 동일 상품의 메입가격이 1월과 4월이 다른경우도 있음)
Alias는 상품코드,매입가,매입수량합계--1월 상품별 매입수량 1월 결과 밖에 안나옴 BUY_PROD,SUM(BUY_QTY)이 같은것을 빼야하는데 1월39,4월26 SUM개수 달라서 하나도 안뺴짐 오류! SELECT BUY_PROD, SUM(BUY_QTY) FROM BUYPROD WHERE BUY_DATE BETWEEN '20050101' AND '20050131' GROUP BY BUY_PROD MINUS SELECT BUY_PROD, SUM(BUY_QTY) FROM BUYPROD WHERE BUY_DATE BETWEEN '20050401' AND '20050430' GROUP BY BUY_PROD ORDER BY BUY_PROD;
728x90'데이터베이스' 카테고리의 다른 글
이클립스에 eXERD설치하기 (0) 2022.03.11 Oracle(2022.03.10)-Package (0) 2022.03.10 Oracle(2022.02.11)-문자열 함수('||',CONCAT,LOWER, UPPER, INITCAP,LPAD, RPAD,LTRIM, RTRIM,TRIM,SUBSTR) (0) 2022.02.11 Oracle(2022.02.09)2-연산자 (0) 2022.02.09 Oracle(2022.02.09) -날짜자료,기타자료형 (0) 2022.02.09