포스트

[SQL 고급] 부속질의

1. 부속질의란?

  • 하나의 SQL 문 안에 다른 SQL 문이 중첩된(nested) 질의
  • 다른 테이블에서 가져온 데이터로 현재 테이블에 있는 정보를 찾거나 가공할 때 사용
  • 보통 데이터가 대량일 때 데이터를 모두 합쳐서 연산하는 조인보다 필요한 데이터만 찾아서 공급해주는 부속질의가 성능이 더 좋음
  • 주질의(main query, 외부질의)부속질의(sub query, 내부질의)로 구성됨

1. 부속질의란

1.1. 부속질의의 종류

명칭위치영문 및 동의어설명
스칼라 부속질의SELECT 절scalar subquerySELECT 절에서 사용되며 단일 값을 반환하기 때문에 스칼라 부속질의라고 함.
인라인 뷰FROM 절inline view, table subqueryFROM 절에서 결과를 뷰(view) 형태로 반환하기 때문에 인라인 뷰라고 함.
중첩질의WHERE 절nested subquery, predicate subqueryWHERE 절에 술어와 같이 사용되며 결과를 한정시키기 위해 사용됨. 상관 혹은 비상관 형태.

2. 스칼라 부속질의(scala subquery)

  • SELECT 절에서 사용되는 부속질의로, 부속질의의 결과 값을 단일 행, 단일 열의 스칼라 값으로 반환함
  • 원칙적으로 스칼라 값이 들어갈 수 있는 모든 곳에 사용 가능하며, 일반적으로 SELECT 문과 UPDATE SET 절에 사용됨
  • 주질의와 부속질의와의 관계는 상관/비상관 모두 가능함

2. 스칼라 부속질의 스칼라 부속질의


질의 4-12 마당서점의 고객별 판매액을 보이시오(고객이름과 고객별 판매액을 출력)


정답

1
2
3
4
5
SELECT    (SELECT name
          FROM    Customer cs
          WHERE   cs.custid = od.custid) 'name', SUM(saleprice) 'total'
FROM      Orders od
GROUP BY  od.custid;


질의 결과

nametotal
박지성39000
김연아15000
장미란31000
추신수33000

2. 스칼라 부속질의 - 질의 4-12 작동 방식


질의 4-13 Orders 테이블에 각 주문에 맞는 도서이름을 입력하시오.


정답

1
2
3
4
UPDATE  Orders
SET     bookname = ( SELECT bookname
                     FROM   Book
                     WHERE  Book.bookid=Orders.bookid );


질의 결과

(삽입예정)


3. 인라인 뷰(inline view)

  • FROM 절에서 사용되는 부속질의
  • 테이블 이름 대신 인라인 뷰 부속질의를 사용하면 보통의 테이블과 같은 형태로 사용할 수 있음
  • 부속질의 결과 반환되는 데이터는 다중 행, 다중 열이어도 상관없음
  • 다만 가상의 테이블인 뷰 형태로 제공되어 상관 부속질의로 사용될 수는 없음

질의 4-14 고객번호가 2 이하인 고객의 판매액을 보이시오(고객이름과 고객별 판매액 출력).


정답

1
2
3
4
5
6
7
SELECT    cs.name, SUM(od.saleprice) 'total'
FROM      /* 인라인 뷰 */(SELECT custid, name
          FROM Customer -- 이것을 가지고 상관질의를 사용하면 안 됨
          WHERE custid <= 2) cs,
          Orders od
WHERE     cs.custid = od.custid
GROUP BY  cs.name;


질의 결과

(삽입예정)


3. 인라인 뷰 인라인 뷰

4. 중첩질의

  • 중첩질의(nested subquery) : WHERE 절에서 사용되는 부속질의
  • WHERE 절은 보통 데이터를 선택하는 조건 혹은 술어(predicate)와 같이 사용됨 → 중첩질의를 술어 부속질의(predicate subquery)라고도 함
술어연산자반환 행반환 열상관
비교=, >, <, >=, <=, <>단일단일가능
집합IN, NOT IN다중단일가능
한정(quantified)ALL, SOME(ANY)다중단일가능
존재EXISTS, NOT EXISTS다중다중필수

한정자 -> 시험을 내고 싶었던 내용

  • 한정자는 실무에서 정말 많이 쓰이는 내용임

4.1. 비교 연산자

  • 부속질의가 반드시 단일 행, 단일 열을 반환해야 하며, 아닐 경우 질의를 처리할 수 없음

질의 4-15 평균 주문금액 이하의 주문에 대해서 주문번호와 금액을 보이시오.


정답

1
2
3
SELECT  orderid, saleprice
FROM    Orders
WHERE   saleprice <= (SELECT AVG(saleprice) FROM Orders);


질의 결과



질의 4-16 각 고객의 평균 주문금액보다 큰 금액의 주문 내역에 대해서 주문번호, 고객번호, 금액을 보이시오.


정답

1
2
3
4
5
SELECT  orderid, custid, saleprice
FROM    Orders od
WHERE   saleprice > (SELECT AVG(saleprice)
                    FROM    Orders so
                    WHERE   od.custid=so.custid);


질의 결과


4.2. IN, NOT IN

  • IN 연산자는 주질의 속성 값이 부속질의에서 제공한 결과 집합에 있는지 확인하는 역할을 함
  • IN 연산자는 부속질의의 결과 다중 행을 가질 수 있음
  • 주질의는 WHERE 절에 사용되는 속성 값을 부속질의의 결과 집합과 비교해 하나라도 있으면 참이 됨
  • NOT IN은 이와 반대로 값이 존재하지 않으면 참이 됨

질의4-17 대한민국에 거주하는 고객에게 판매한 도서의 총판매액을 구하시오.


정답

1
2
3
4
5
SELECT  SUM(saleprice) 'total'
FROM    Orders
WHERE   custid IN (SELECT custid
                  FROM    Customer
                  WHERE   address LIKE '%대한민국%');


질의 결과 | total | | —– | | 46000 |


4.3. ALL, SOME(ANY)

  • ALL은 모두, SOME(ANY)은 어떠한(최소한 하나라도)이라는 의미
  • 구문 구조
1
2
3
scalar_expression 
  { cmp_op( =, <>, !-, >, !>, <, <=, !< ) } 
  { ALL | SOME | ANY } (subquery)

주의사항

ANY 연산자는 일부 오래된 데이터베이스 시스템에서 지원하지 않을 수 있다.

4.4. EXISTS, NOT EXISTS

  • 데이터의 존재 유무를 확인하는 연산자
  • 주질의에서 부속질의로 제공된 속성의 값을 가지고 부속질의에 조건을 만족하여 값이 존재하면 참이 되고, 주질의는 해당 행의 데이터를 출력함
  • NOT EXIST의 경우 이와 반대로 동작함
  • 구문 구조
1
WHERE [NOT] EXISTS (subquery)
이 포스팅은 작성자의 CC BY-NC 4.0 라이선스를 준수합니다.