DB. MySQL 6. 쿼리 안에 서브쿼리

JINSOO PARK·2021년 11월 15일
0

DB 강의

목록 보기
7/7

서브쿼리

링크텍스트


1. 비상관 서브쿼리

쿼리문 안쪽의 또다른 쿼리문 으로 바깥쪽의 쿼리와 안쪽의 서브쿼리문은 독자적으로 실행되며 서로 상관하지 않는다.


ex1)

SELECT
  CategoryID, CategoryName, Description,
  (SELECT ProductName FROM Products WHERE ProductID = 1)
FROM Categories;

쿼리문 안에 또 다른 쿼리문을 넣어서 다른 테이블에서 데이터를 불러옴


ex2)

SELECT * FROM Products
WHERE Price < (
  SELECT AVG(Price) FROM Products
);

서브쿼리를 이용해서 Price의 평균을 구하고 평균 보다 낮은 값을 추출한다.


ex3)

SELECT CategoryID, CategoryName, Description
FROM Categories;

Categories테이블의 CategoryID, CategoryName, Description 컬럼


ex3-1)

SELECT CategoryID FROM Products
  WHERE Price > 50;

Poducts 테이블의 Price가 50보다 큰 값을 가진 CategoryID들


ex3-2)합쳐 보기

Poducts 테이블의 Price가 50보다 큰 값을 가진 CategoryID를 추출해서 Categories테이블의 CategoryName, Description 컬럼을 데이터를 불러옴


ALL, ANY


연산자의미
~ALL서브쿼리의 모든 결과에 대해 ~하다
~ANY서브쿼리의 하나 이상의 결과에 대해 ~하다

ex1) ALL

SELECT Price FROM Products 
WHERE CategoryID =2;

CategoryID가 2인 것 들을 추출해서 Price를 보여줌


ex1-1) ALL 적용

SELECT * FROM Products
WHERE Price > ALL(
SELECT Price FROM Products 
WHERE CategoryID =2
);

CategoryID가 2인 것 들의 Price보다 큰 Price 값을 보여준다. 즉 CategoryID가 2인 것 들 중 Max값 보다 큰 값을 보여줌


ex2) ANY

SELECT CategoryID FROM Products 
WHERE Price > 50;

Price가 50보다 큰 값의 CategoryID


ex2-1) ANY 적용

SELECT CategoryID, CategoryName, Description 
FROM Categories
WHERE CategoryID = ANY (
SELECT CategoryID FROM Products 
WHERE Price > 50);

Price가 50보다 큰 값의 CategoryID 중 같은 값이 있으면 해당 값을 보여준다.
"CategoryID = ANY" == "CategoryID IN"



2. 상관 서브쿼리

바깥쪽의 쿼리와 안쪽의 서브쿼리가 맡물려 돌아간다.


ex1)

Products 테이블

Categories 테이블

Products 테이블은 CategoryID를 가지고 있고,
Categories는 각 각의 CategoryID가 가지는 데이터들이 있다.


SELECT ProductID, ProductName,
(
SELECT CategoryName FROM Categories C
WHERE C.CategoryID = P.CategoryID
) AS CategoryName
FROM Products P;

  1. Categories C, Products P 각 테이블의 별명을 정함
  2. P 테이블에서 ProductID, ProductName을 가져옴
  3. C 테이블에서 CategoryName을 가져옴
  4. C. CategoryID 와 P. Category 아이디가 같은 것끼리 묶음
  5. P 테이블의 ProductID, ProductName 와 C 테이블의 CategoryName을 한 테이블에서 볼 수 있음

ex2)

Suppliers 테이블

Customers 테이블

각 각의 테이블이 가지고있는 County와 City 정보를 이용해 하나의 테이블로 정리한다.

SELECT SupplierName, Country, City,
(
SELECT COUNT(*) FROM Customers C
WHERE C.Country = S.Country
) AS CustomersInTheCountry,
(
SELECT COUNT(*) FROM Customers C
WHERE C.Country = S.Country AND C.City = S.City
) AS CustomersInTheCity 
FROM Suppliers S;

  1. Suppliers S, Customers C 각 테이블의 별명
  2. S 테이블에서 SupplierName, Country, City 정보를 가져옴
  3. C 테이블에서 C와 S의 Country 정보가 같은 테이터를 가져와서 COUNT, 컬럼명 CustomersInTheCountry
  4. C 테이블에서 C와 S의 Country 정보가 같고 C와 S의 City 정보가 같은 것들을 COUNT, 컬럼명 CustomersInTheCity
  5. 그 결과를 한 테이블에서 보여줌

EXISTS / NOT EXISTS

연산자의미
EXISTS존재 하는가
NOT EXISTS존재하지 않는가

ex1) EXISTS

SELECT CategoryID, CategoryName 
FROM Categories C
WHERE EXISTS(
SELECT * FROM Products P
WHERE P.CategoryID = C.CategoryID AND P.Price > 80
);

P.Category Id 와 C.CategoryID가 같은고 price가 80이 넘어가는 데이터가 존재한다면 해당 데이터를 보여준다.


ex2) NOT EXISTS

SELECT CategoryID, CategoryName 
FROM Categories C
WHERE NOT EXISTS(
SELECT * FROM Products P
WHERE P.CategoryID = C.CategoryID AND P.Price > 80
);

P.Category Id 와 C.CategoryID가 같은고 price가 80이 넘어가는 데이터가 존재하는것을 제외하고 보여준다.

profile
개린이

0개의 댓글