두 개 이상의 테이블 다루기 - 집합 연산과 EXISTS

hyeh·2022년 8월 24일
0

SQL 기초

목록 보기
6/9

집합연산

반한된 결과를 하나의 집합이라고 생각하고 합집합교집합,차집합을 구할 수 있다.

샘플 데이터

JOIN과 동일한 마당 서점의 데이터를 활용했다.

합집합(UNION)

합집합은 집합을 서로 더한 것을 말한다. SELECT 명령의 실행 결과를 하나의 집합으로 다룰 수 있으며, UNION 키워드를 사용한다.

  • UNION으로 두 개의 SELECT 명령을 하나로 연계해 질의 결과를 얻을 수 있다.
  • 이때 각 SELECT 명령에 ORDER BY를 지정해 정렬할 수는 없다.
    • 마지막 SELECT 명령에만 지정 가능
  • UNION을 사용하면 자연스럽게 중복이 제거되는데, 중복을 제거하지 않고 합치고 싶을 땐 UINON ALL을 사용한다.

예제1. 대한민국 거주하는 고객의 이름과 도서를 주문한 고객의 이름

  • {고객이름} = {대한민국에거주하는고객이름} ∪ {도서를주문한고객이름}
SELECT name
FROM customer
WHERE address LIKE '대한민국%'
UNION
SELECT name
FROM customer
WHERE custid IN (SELECT custid
				FROM orders);
  • ⚠️ 나의 답 : 실행 결과는 같음
SELECT name
FROM customer
WHERE address LIKE '대한민국%'
UNION
SELECT name
FROM customer 
	JOIN orders
    ON customer.custid = orders.orderid;

교집합과 차집합

MySQL에는 교집합과 차집합을 다루는 INTERSECT, MINUS 연산자가 없으므로 다음과 같이 표현한다.

예제2. 교집합 연산

  • IN 연산자를 사용해 교집합을 계산할 수 있다.
  • 대한민국에 거주하는 고객 중 도서를 주문한 고객의 이름
SELECT name
FROM customer
WHERE address LIKE '대한민국%'
AND name IN (SELECT name
			FROM customer
            WHERE custid IN (SELECT custid
							FROM orders));

예제3. 차집합 연산

  • NOT IN 연산자를 사용해 차집합을 계산할 수 있다.
  • 대한민국에 거주하는 고객의 이름에서 도서를 주문한 고객의 이름 제외
SELECT name
FROM customer
WHERE address LIKE '대한민국%'
AND name NOT IN (SELECT name
				FROM customer
                WHERE custid IN (SELECT custid
								FROM orders));

EXISTS

서브쿼리를 사용해 검색할 때 데이터가 존재하는지 아닌지를 판별하기 위해 EXISTS를 사용할 수 있다.

  • 사용: EXISTS (SELECT 명령)
  • EXISTS는 원래 단어에서 의미하는 것과 같이 조건에 맞는 튜플이 존재하면 결과에 포함시킨다.
  • 즉, 서브쿼리의 어떤 행이 조건에 만족하면 참임
  • NOT EXISTS는 서브쿼리의 모든 행이 조건에 만족하지 않을 때만 참임

예제4: 주문이 있는 고객의 이름과 주소

  • 1단계 orders 테이블과 customer 테이블을 부속질의로 연결한다
  • 이때 'custid가 같다'라는 조인조건을 넣어준다
  • 2단계 customer 테이블에서 name과 address를 존재하는 것만 뽑아준다
SELECT name, address
FROM customer
WHERE EXISTS (SELECT * -- 서브쿼리 안에 있다 없다
			FROM orders
			WHERE customer.custid = orders.custid); -- 존재 여부는 custid로 찾겠다.
            -- 반환되는 행이 없으면 거짓!
  • 실행 프로세스
    • 이그지스트는 존재 하는지 안 하는지가 중요한 조건이다!!!!
  • EXISTS는 IN이나 JOIN으로 대체할 수 있다.
  • 단, JOIN은 결합을 시켜서 해당하는 칼럼을 보여주는 것이며, EXISTS는 존재 한다, 안한다의 의미가 더 크다
  • 목적에 따라 사용하는 게 중요
  • EXISTS는 NOT EXISTS로, 주문을 한 번도 안 한 고객 정보를 알고 싶을 때 많이 사용한다.
-- 주문 이력이 없는 사람 찾기 : NOT EXISTS
SELECT name, address
FROM customer
WHERE NOT EXISTS (SELECT * 
			FROM orders
			WHERE customer.custid = orders.custid); 
  • NOT IN, 또는 LEFT JOIN 후 NULL 값을 찾는 것으로 동일한 값을 구할 수 있다.
  • NOT EXISTS는 전체를 다 대조하지 않고 한 번만 맞아도 TRUE로 판단하게 때문에 실행 속도가 빠르다.
  • 즉, 없는 거 찾을 때는 NOT EXISTS가 제일 좋다!!
profile
좌충우돌 천방지축 룰루랄라 데이터 공부

0개의 댓글