오늘은 SQL 강좌를 이어 들어 상관 서브 쿼리에 대해 공부했다.
메인쿼리를 먼저 실행하고 메인 쿼리의 1레코드 마다 서브쿼리를 실행하는 쿼리
일반적인 서브쿼리는 서브쿼리가 먼저 실행되고 난 뒤 메인쿼리가 실행된다.
상관 서브 쿼리는 메인 쿼리의 값을 참조한다.
FROM 구에서 사용할 수 없다.
SELECT 컬럼명
FROM 테이블A
WHERE 값 연산자
(
SELECT ~
FROM 테이블B
WHERE 테이블A.컬럼C = 테이블B.컬럼C
);
SELECT 컬럼명,
(
SELECT ~
FROM 테이블B
WHERE 테이블A.컬럼C = 테이블B.컬럼C
)
FROM 테이블A;
product 테이블의 상품 중에서 productorder 테이블의 정보로부터 상품마다의 합계 매상 개수가 3보다 큰 상품의 정보를 가져와라
메인 쿼리의 대상은 product 테이블. product 테이블의 1 레코드 마다 서브쿼리를 실행한다.
메인쿼리와 서브쿼리에서 테이블이 2개가 나오므로 테이블명.컬럼명
으로 표기해 컬럼을 구분한다. 어느 테이블인지 명확한건 굳이 안붙여도 된다.
상관 서브쿼리가 WHERE구 안에서 메인쿼리의 1레코드씩 실행될때 같이 계속 실행된다.
SELECT product.product_id, product.product_name
FROM product
WHERE 3 < (
SELECT SUM(quantity)
FROM productorder
WHERE product.product_id = productorder.product_id
);
customer 테이블에서 customer_id와 customer_name에 대해 productorder 테이블에서 고객마다의 합계 구입 금액을 가져와라.
SELECT a.customer_id, a.customer_name,
(
SELECT SUM(b.price)
FROM productorder AS b
WHERE a.customer_id = b.customer_id
) AS total
FROM customer AS a;
EXISTS(서브쿼리) 로 사용해 서브쿼리의 결과가 존재하면 1을 반환한다.
상관 서브쿼리의 결과에 사용하는 연산자이다.
예시
product 테이블에서 productorder 테이블에 주문 기록이 있는 상품의 정보를 가져와라
EXISTS(서브쿼리)의 형태로 사용한다. 결과는 TRUE(1) or FALSE(0)로 반환되어 연산된다.
SELECT a.product_id, a.product_name
FROM product AS a
WHERE EXISTS
(
SELECT *
FROM productorder AS b
WHERE a.product_id = b.product_id
);
어떤 릴레이션에 소속된 속성 또는 속성 집합이 다른 릴레이션의 기본키가 되는 키
productorder 테이블
customer 테이블의 customer_id는 PK(기본키)로 유일한 값을 가진다. 그리고 productorder의 customer_id 컬럼은 저 컬럼과 관계
를 가진다. 이때 productorder의 customer_id 컬럼은 FK(외래키)가 된다.
참조 무결성
: 외래키는 다른 테이블의 기본키이다. 따라서, 다른 테이블의 기본키로 없는 데이터를 외래키로 삼을 수 없다.
ex) customer_id가 1~100까지라면 이를 외래키로 쓰는 컬럼에선 1~100 이외의 다른 값이 들어갈 수 없다.
복수의 테이블을 사용하는 상관 서브 쿼리에서 테이블명이 비슷하거나 길면 번거롭거나 착오가 생길 수 있다. 따라서 AS를 사용해 테이블에 별명을 붙이는 것이 가독성 측면에서 좋다.
SELECT a.product_id, a.product_name
FROM product AS a
WHERE 3 < (
SELECT SUM(quantity)
FROM productorder AS b
WHERE a.product_id = b.product_id
);