서브쿼리
쿼리문 안에 또 다른 쿼리문이 들어있음.
서브쿼리의 결과 값을 사용하여 메인쿼리를 수행함.
서브쿼리는 WHERE 절의 연산자 오른쪽에 위치해야 하며 반드시 괄호를 사용해야함
서브쿼리문을 먼저 확인해보는 것이 오류를 줄이는 방법
메인쿼리문에서 지정한 별칭은 서브쿼리문에서 사용할 수 없음
일반 서브쿼리문은 결과를 하나의 값처럼 사용
단일행 서브쿼리 : 서브쿼리의 결과가 하나만 산출
- 결과가 하나만 나오는 다중행함수 등이 서브쿼리에 들어감
- 단일행 연산자 : >, >=, <, <=, =, !=
SELECT * FROM table
WHERE column2 > ( SELECT column2
FROM table
WHERE column1 = 'A');
-> 메인쿼리 조건절에 있는 컬럼과 서브쿼리의 SELECT절에 있는 컬럼이 같아야함 (column2 = column2)
다중행 서브쿼리 : 서브쿼리의 결과가 여러개 산출
- 결과가 여러개 나오는 단일행함수 등이 서브쿼리에 들어감
- 다중행 연산자
- IN : or 같은 역할, 같은 값을 찾음(=)
- ANY, SOME : 하나이상 만족이면 true ( > ANY : 최소값 / < ANY : 최대값)
- ALL : 모두 만족이면 true ( >ALL : 최대값 / < ANY : 최소값)
- EXISTS : 값이 하나라도 존재하면 true
-- 서브쿼리가 단일행일 경우 --
SELECT * FROM table
WHERE column2 = ( SELECT AVG(column2) -- 서브쿼리 결과로 평균값 하나만 나옴
FROM table
WHERE column1 = 'A');
-- 서브쿼리가 다중행일 경우 --
SELECT * FROM table
WHERE column2 IN ( SELECT column2 -- 서브쿼리 결과로 여러개가 나옴
FROM table
WHERE column1 = 'A');
다중열(컬럼) 서브쿼리
- WHERE절에서 ( )를 사용하여 다중열을 사용 할 수 있음
- WHERE절과 서브쿼리의 SELECT절의 컬럼 갯수와 종류가 같아야함
SELECT * FROM table
WHERE (column1, column2) IN (SELECT column1, AVG(column2)
FROM table;
▷ 상호 연관 서브쿼리 : 메인쿼리와 서브쿼리의 연결이 필요할 때 사용
- 다중열 서브쿼리 (비선호) -> 상호 연관 서브쿼리 (선호) 변경 가능
- 메인쿼리의 행을 하나씩 가져와서 서브쿼리에 대입해서 비교
(메인쿼리의 테이블을 메모리에 올리고 위에서부터 차례로 행을 하나씩 가져와서 비교 후 조건 충족시에만 남겨놓음) - 메인쿼리의 테이블에 별칭을 정한 후 서브쿼리에서 호출
SELECT * FROM table m
WHERE column2 = ( SELECT AVG(column2)
FROM table
WHERE m.column1 = column1);
서브쿼리의 WHERE절에서 왼쪽항은 메인쿼리의 테이블, 오른쪽항은 서브쿼리의 테이블임
즉, 서브쿼리에서 메인쿼리의 데이터를 사용
서브쿼리의 WHERE절이 GROUP BY역할을 한다고 생각
스칼라 서브쿼리 : SELECT절의 컬럼에 서브쿼리를 사용 -> 하나의 컬럼처럼 사용
- 조인 (선호) -> 스칼라 서브쿼리 (비선호) 변경 가능
SELECT column1, (SELECT column2 FROM table2
WHERE m.column1 = column1)
FROM table1 m
WHERE column3 = 'A';
-> 스칼라 서브쿼리와 상호 연관 서브쿼리를 같이 사용
인라인(Inline) 뷰 : FROM절에 서브쿼리를 사용 -> 하나의 테이블처럼 사용
- 1회용 뷰
SELECT a.column1, a.column2, b.column1, b.column2
FROM (SELECT * FROM table1 WHERE column1 = 'A') a
(SELECT * FROM table2 WHERE column1 = 'A') b
WHERE a.column1 = b.column1;
동일한 : 상호연관 / 외래키,여러테이블 : 스칼라&조인 / 전체 행을 바꿀때: 인라인