SQL기본(7): 서브쿼리
1. 서브쿼리
-쿼리 안에 포함된 또 다른 쿼리
-조인하지 않은 상태에서 다른 테이블과 일치하는 행을 찾을 수 있음
-조인 결과를 다시 조인할 때 사용 가능(여러 번 쿼리 수행결과 -> 하나의 중첩된 문장으로 간편 조회)
-비교 연산자 서브 쿼리 사용 시 오른쪽 기술, 내부에는 ORDER BY 사용 불가, 여러 개의 서브쿼리 중첩가능
-다중행 연산자 종류: (IN, ANY, EXISTS, ALL)
-비교 연산자와 사용 시 결과가 반드시 1건, 결과가 2건 이상일 경운 다중행 연산자 사용 필요
2. 종류:
-
더보기단일행 서브쿼리: 서브 쿼리에서 반환되는 결과가 1개 SELECT <col> FROM [TABLE] WHERE <col> = (SELECT <col> FROM [TABLE])
-
더보기다중행 서브쿼리: 서브 쿼리에서 반환되는 결과가 2행 이상 SELECT <col> FROM [TABLE] WHERE symbol IN ('AA', 'BB' , 'CC')
- WHERE 서브쿼리 = 중첩 서브쿼리 = 상관 하위 쿼리,
- (LEFT, RIGHT, FULL) OUTER JOIN(모두 출력, 조건에 만족하지 않아도 해당 테이블 관련 출력)
- CROSS JOIN(조인에 포함된 테이블의 카티션 곱, 조인 조건이 없음)
- SELF JOIN(같은 테이블을 사용, 계층적 구조를 테이블화에 사용, AS명 반드시 사용, JOIN구문 없음)
- FROM 절 서브 쿼리: 인라인 뷰, SELECT 결과를 FROM 절에서 하나의 테이블 처럼 사용 /SQL SERVER: AS필요
- Scalar서브쿼리: select문에 사용, 반드시 1개의 행 반환
1. SELECT <col> FROM INNER JOIN [table2] as T2 on T1.col1 = T2.col1 WHERE <col> = [value] ORDER BY [col]
-JOIN ON과 WHERE의 차이: ON은 조인 조건을 위한, WHERE은 조인 완료 후 조건에 맞는 값 필터를 위한
2. SELECT <col> FROM <LEFT, RIGHT, FULL> OUTER JOIN [table2] as T2 on T1.col1 = T2.col1
WHERE <col> = [value] ORDER BY [col]
-왼, 오 기준 테이블 지정, FULL OUTER는 모두 표시(합집합)
3. SELECT <col> FROM CROSS JOIN [table2] as T2
4. SELECT <col> T1.<col>, T2.<col> FROM [table1] as T1 INNER JOIN [table1] as T2 on T1.col1 = T2.col1
-- UPDATE를 통한 서브쿼리 구성
CREATE TABLE doit_subquery_a(
col_1 INT,
col_2 NVARCHAR(50)
)
INSERT INTO doit_subquery_a VALUES (1, N'AAA')
INSERT INTO doit_subquery_a VALUES (2, N'BBB')
INSERT INTO doit_subquery_a VALUES (3, N'CCC')
INSERT INTO doit_subquery_a VALUES (4, N'DDD')
INSERT INTO doit_subquery_a VALUES (5, N'EEE')
CREATE TABLE doit_subquery_b(
col_1 INT,
col_2 NVARCHAR(50)
)
INSERT INTO doit_subquery_b VALUES (1, N'111')
INSERT INTO doit_subquery_b VALUES (2, N'222')
INSERT INTO doit_subquery_b VALUES (3, N'333')
INSERT INTO doit_subquery_b VALUES (4, N'444')
INSERT INTO doit_subquery_b VALUES (5, N'555')
UPDATE a
SET a.col_2 = (SELECT b.col_2 FROM doit_subquery_b AS b WHERE b.col_1 = a.col_1)
FROM doit_subquery_a AS a
SELECT * FROM doit_subquery_a
SELECT * FROM doit_subquery_b
DROP TABLE doit_subquery_A
--INSERT INTO를 통한 서브쿼리 구성
INSERT INTO doit_subquery_a (col_1, col_2)
SELECT col_1, col_2 FROM doit_subquery_b
-- 하위쿼리 값이 2개일 경우 등호나 비교연산자 필요 / 서브쿼리는 한 개의 값 반환
INSERT INTO doit_subquery_a (col_1, col_2)
VALUES ((SELECT col_1 FROM doit_subquery_b WHERE col_1 = 1),
(SELECT col_2 FROM doit_subquery_b WHERE col_1 = 1))
-- WHERE 서브 쿼리
SELECT * FROM nasdaq_company
WHERE symbol = (SELECT symbol FROM nasdaq_company WHERE symbol = N'MSFT')
SELECT * FROM nasdaq_company
WHERE symbol NOT IN (SELECT symbol FROM nasdaq_company WHERE symbol IN(N'AMD', N'MSFT'))
SELECT a.industry, c.symbol, c.company_name, c.ipo_year, c.sector
FROM industry_group AS a
INNER JOIN industry_group_symbol AS b ON a.num = b.num
INNER JOIN nasdaq_company AS c ON b.symbol = c.symbol
WHERE a.industry = N'자동차'
ORDER BY symbol
SELECT
*
FROM nasdaq_company
WHERE symbol IN(
SELECT symbol
FROM industry_group AS a
INNER JOIN industry_group_symbol AS b ON a.num = b.num
WHERE a.industry = N'자동차'
)
--다중행 서브쿼리 연산
SELECT * FROM nasdaq_company
WHERE symbol = ANY(
SELECT symbol FROM nasdaq_company
WHERE symbol IN ('MSFT', 'AMD', 'AMZN')
)
--IN 안에 있는 것보다 작은 값 찾기
SELECT * FROM nasdaq_company
WHERE symbol < ANY(
SELECT symbol FROM nasdaq_company
WHERE symbol IN ('MSFT', 'AMD', 'AMZN')
)
-- 서브쿼리 값이 맞을 시 TRUE를 반환, 값이 있는걸 반환
SELECT * FROM nasdaq_company
WHERE EXISTS (
SELECT symbol FROM nasdaq_company
WHERE symbol IN ('MSFT', 'AMD', 'AMZN')
)
-- ALL 조건을 모두 만족하는 것을 출력
SELECT * FROM nasdaq_company
WHERE symbol = ALL(
SELECT symbol FROM nasdaq_company
WHERE symbol IN ('MSFT', 'AMD', 'AMZN')
)
--SELECT 서브쿼리(스칼라 쿼리)
SELECT * FROM(
SELECT* FROM DoItSQL.DBO.nasdaq_company
) AS a --AS 별칭 필요
SELECT
a.*
FROM DoItSQL.dbo.nasdaq_company AS a
INNER JOIN(
SELECT TOP 10 symbol FROM DoItSQL.dbo.nasdaq_company
WHERE symbol LIKE 'A%'
ORDER BY ipo_year ) AS b ON a.symbol = b.symbol
SELECT
a.symbol, a.company_name, a.ipo_year, a.sector, a.industry,
b.date, b.[open], b.[high], b.[low], b.[close], b.adj_close, b.volume
FROM DoItSQL.DBO.nasdaq_company AS a
INNER JOIN DoItSQL.DBO.stock AS b ON a.symbol = b.symbol
INNER JOIN DoItSQL.DBO.industry_group_symbol AS c ON a.symbol = c.symbol
INNER JOIN DoItSQL.DBO.industry_group AS d ON c.num = d.num
WHERE a.symbol = 'MSFT'
SELECT
a.symbol, a.company_name, a.ipo_year, a.sector, a.industry,
b.date, b.[open], b.[high], b.[low], b.adj_close, b.volume
FROM DoItSQL.dbo.nasdaq_company AS a
INNER JOIN DoItSQL.dbo.stock AS b ON a.symbol = b.symbol
WHERE a.symbol = N'MSFT'
AND b.date >= '2021-10-01'
AND b.date < '2021-11-01'
SELECT
a.date, a.[open], a.[high], a.[low], a.adj_close, a.volume,
(SELECT company_name FROM DOITSQL.DBO.nasdaq_company AS b WHERE b.symbol = a.symbol) AS COMPANY_NAME,
(SELECT ipo_year FROM DOITSQL.DBO.nasdaq_company AS b WHERE b.symbol = a.symbol) AS ipo_NAME,
(SELECT sector FROM DOITSQL.DBO.nasdaq_company AS b WHERE b.symbol = a.symbol) AS sec_NAME
FROM DoItSQL.dbo.stock AS a
WHERE symbol = N'MSFT'
AND date >= '2021-10-01'
AND date < '2021-11-01'