집합연산자

서현서현·2022년 2월 28일
0

DB, SQL

목록 보기
17/27
post-thumbnail

🤖 집합연산자

  • 합집합(UNION, UNION ALL), 교집합(INTERSECT), 차집합(MINUS)결과를 반환하는 연산자
  • 집합연산자의 대상은 SELECT문의 결과이다
  • 조인 등의 복잡한 연산을 줄일 수 있다
  • 모든 SELECR문의 컬럼의 수, 데이터타입, 순서가 일치해야함
  • 첫 SELECT문에 적용된 컬럼타입, 이름이 기준이됨
  • CLOB, BLOB, BFILE 타입은 사용불가
  • ORDER BY 절은 맨 마지막 SELECT 문에만 사용 가능

🤖 1. UNION, UNION ALL

  • 합집합의 결과를 교집합부분의 중복없이(UNION), 중복하여(UNION ALL) 반환한다
(사용형식)
SELECT 컬럼List
FROM 테이블명
[WHERE 조건]
UNION | UNION ALL
			.
			.
SELECT 컬럼List
FROM 테이블명
[WHERE 조건]
[ORDER BY 컬럼명];
  • 첫번째 SELECT문의 결과와 나머지 SELECT문의 결과가 결합하여 반환

(EX1) 장바구니테이블에서 2005년 5월과 7월에 구매한 모든 회원을 조회하시오.

Alias는 회원번호, 회원명, 주소, 마일리지

SELECT 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(A.CART_NO,1,6) IN('200505','200507')
ORDER BY 1;

--UNION
 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(A.CART_NO,1,6) = '200505'
UNION
 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(A.CART_NO,1,6) = '200507'
-- 23명, 중복자료 안나옴

-- UNION ALL
 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(A.CART_NO,1,6) = '200505'
UNION ALL
 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(A.CART_NO,1,6) = '200507'
-- 5월 7월 5월 7월 사던 사람들..... 31건(5,7월에 구매한, 중복인원 나옴)

(EX2) 2005년 2월과 6월 매입된 상품을 모두 조회하시오

Alias는 상품코드, 상품명

 SELECT DISTINCT BUY_PROD AS 상품코드,
								PROD_NAME AS 상품명
	 FROM BUYPROD, PROD
	WHERE BUY_DATE BETWEEN TO_DATE('20050201')
				AND LAST_DAY(TO_DATE('20050201'))
				AND BUY_PROD = PROD_ID;
--UNION
--INTERSECT
--UNION ALL
 SELECT DISTINCT BUY_PROD AS 상품코드,
						 		PROD_NAME AS 상품명
	 FROM BUYPROD, PROD
  WHERE BUY_DATE BETWEEN TO_DATE('20050601')
								AND LAST_DAY(TO_DATE('20050601'))
								AND BUY_PROD = PROD_ID;

🤖 2. INTERSECT

  • 교집합의 결과를 반환

(EX1) 사원테이블과 직무변동테이블(JOB_HISTORY)에서 사원번호와 직책코드와 같은 사원을 조회하시오

집합연산자없이 구현)
SELECT A.EMPLOYEE_ID AS 사원번호,
        A.JOB_ID AS 직책코드,
        A.EMP_NAME AS 사원명
FROM HR.EMPLOYEES A
WHERE (A.EMPLOYEE_ID, A.JOB_ID) =ANY(SELECT EMPLOYEE_ID, JOB_ID
                                    FROM HR.JOB_HISTORY);
                                    
(집합연산자 사용)
 SELECT EMPLOYEE_ID AS 사원번호,
        JOB_ID AS 직책코드
        FROM HR.EMPLOYEES
INTERSECT
        SELECT EMPLOYEE_ID,
                JOB_ID
        FROM HR.JOB_HISTORY

(EX3) 2005년 4월 5월 6월에 공통으로 매입된 상품을 모두 조회하시오

Alias는 상품코드,상품명

SELECT B.BUY_PROD AS 상품코드,
             A.PROD_NAME AS 상품명
        FROM PROD A, BUYPROD B
       WHERE A.PROD_ID = B.BUY_PROD
       AND B.BUY_DATE BETWEEN '20050401' AND '20050431'
INTERSECT
      SELECT B.BUY_PROD,
             A.PROD_NAME
        FROM PROD A, BUYPROD B
       WHERE A.PROD_ID = B.BUY_PROD
       AND B.BUY_DATE BETWEEN '20050501' AND '20050531'
INTERSECT
      SELECT B.BUY_PROD,
             A.PROD_NAME
        FROM PROD A, BUYPROD B
       WHERE A.PROD_ID = B.BUY_PROD
       AND B.BUY_DATE BETWEEN '20050601' AND '20050631'
**(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%'
   
   
SELECT DISTINCT CART_PROD AS AID
FROM CART
WHERE CART_NO LIKE '200504%'
    
    -- 2005년 5월에 판매된 상품코드, 상품명
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 '200505%'
    
    
    
SELECT DISTINCT CART_PROD AS BID
FROM CART
WHERE A.CART_NO LIKE '200505%'
    
    -- 2005년 6월에 판매된 상품코드, 상품명
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 '200506%'
    
SELECT DISTINCT CART_PROD AS CID
FROM CART
WHERE CART_NO LIKE '200506%'

--결합
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 -- 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;
**(집합연산자를 사용한 결합)**

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,
        B.PROD_NAME
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 (차집합)

  • 복수개의 쿼리결과에 대해 차집합의 결과 반환

(EX1) 매입테이블에서 2005년 1월과 4월의 매출을 비교하여 1월에만 판매된 상품정보를 출력하시오. (단, 동일상품의 판매가격이 1월과 4월이 다른경우도 있음)

Alias는 상품코드, 상품명, 매입가, 판매가

(1월 상품별 매입수량)

      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;

0개의 댓글