[데이터베이스] SQL 질의 - 조인(JOIN), 부속질의(Subquery), 집합 연산

01_조인(JOIN)


☾ 조인

한 테이블의 행을 다른 테이블의 행에 연결해 두 개 이상의 테이블을 결합

관계 대수의 카티션 프로덕트 연산

같은 속성 이름을 사용하는 테이블이 두 개 이상일 경우, ‘테이블이름.열이름‘ 형식으로 표현하여 열 이름이 어느 테이블과 연관되는지 정확히 명시해야 한다.

-- 고객과 고객의 주문에 관한 데이터를 모두 나타내시오.

SELECT *
FROM Customer, Orders
WHERE Customer.custid=Orders.custid;

 

  • LEFT OUTER JOIN
-- 도서를 구매하지 않은 고객을 포함해 고객의 이름과 고객이 주문한 도서의 판매가격을 구하시오.

SELECT Customer.name, saleprice
FROM Customer LEFT OUTER JOIN Orders ON Customer.custid=Orders.custid;

 

 

 

☾ 동등 조인

동등 조건에 의하여 테이블 조인

-- 고객의 이름과 고객이 주문한 도서의 판매가격을 검색하시오.

SELECT name, saleprice
FROM Customer, Orders
WHERE Customer.custid=Orders.custid;

-- 가격이 20000원인 도서를 주문한 고객의 이름과 도서의 이름을 구하시오.

SELECT Customer.name, Book.bookname
FROM Customer, Orders, Book
WHERE Customer.custid=Orders.custid AND Orders.bookid=Book.bookid AND Book.price=20000;

 

 

 

☾ 셀프 조인

하나의 테이블을 대상으로 조인

-- 사원 '김하나'가 관리하는 부하 사원의 이름과 직급을 출력하시오.

SELECT staff.name, staff.level
FROM Person staff, Person manager
WHERE staff.mgr = manager.num AND manager.name LIKE '김하나';

 

 

 

 

02_부속질의(Subquery)


 부속질의

두 질의를 하나로 합치기

SELECT 문의 WHERE절에 또 다른 테이블 결과를 이용하기 위해 다시 SELECT문을 괄호로 묶는 것

 

  • 실행 순서
  1. WHERE절의 부속 질의를 먼저 처리
  2. 전체 질의 처리
-- 가장 비싼 도서의 이름을 나타내시오.

SELECT bookname
FROM Book
WHERE price = (SELECT MAX(price) FROM Book);

 

부속질의의 결과가 다중행-단일열(n×1)로 여러 개의 값을 반환하면 IN 키워드 사용

-- 도서를 구매한 적 있는 고객의 이름을 검색하시오.

SELECT name
FROM Customer
WHERE custid IN (SELECT custid FROM Orders);

 

 

3개 이상의 중첩된 부속질의도 가능하다.

-- 대한미디어에서 출판한 도서를 구매한 고객의 이름을 검색하시오.

SELECT name
FROM Customer
WHERE custid IN (SELECT custid
		FROM Orders
		WHERE bookid IN(SELECT bookid
				FROM Book
				WHERE publisher='대한미디어'));

 

 

 

상관(correlated) 부속질의

상위 부속질의의 투플을 이용하여 하위 부속질의 계산

-- 출판사별로 출판사의 평균 도서 가격보다 비싼 도서를 구하시오.

SELECT b1.bookname
FROM Book b1
WHERE b1.price > (SELECT avg(b2.price)
		FROM Book b2
		WHERE b2.publisher=b1.publisher);

 

 

 

 EXISTS

부속질의문의 어떤 행이 조건에 만족하면 참

상관 부속질의문의 다른 형태

-- 주문이 있는 고객의 이름과 주소를 나타내시오.

SELECT name, address
FROM Customer cs
WHERE EXISTS (SELECT *
		FROM Orders od
		WHERE cs.custid=od.custid);
  • NOT EXISTS : 부속질의문의 모든 행이 조건에 만족하지 않을 때만 참

 

 

 

 

03_집합 연산


 UNION

합집합 계산

UNION ALL : 중복을 포함하여 모든 결과 구함

-- 대한민국에 거주하는 고객의 이름과 도서를 주문한 고객의 이름을 나타내시오.
-- {고객 이름} = {대한민국에 거주하는 고객 이름} ∪ {도서를 주문한 고객 이름}

SELECT name
FROM Customer
WHERE address LIKE '대한민국%'
UNION
SELECT name
FROM Customer
WHERE custid IN (SELECT custid FROM Orders);

 

  • IN : 교집합은 IN 연산자로 계산한다.
SELECT name
FROM Customer
WHERE address LIKE '대한민국%' AND
		name IN (SELECT name
			FROM Customer
			WHERE custid IN (SELECT custid FROM Orders));

 

  • NOT IN : 차집합은 NOT IN 연산자로 계산한다.
SELECT name
FROM Customer
WHERE address LIKE '대한민국%' AND
	name NOT IN (SELECT name
			FROM Customer
			WHERE custid IN (SELECT custid FROM Orders));