본문 바로가기

DEVELOPMENT/SQL

[SQL] 서브쿼리

서브쿼리

 

서브쿼리는 SELECT 명령에 의한 데이터 질의로, 상부가 아닌 하부의 부수적인 질의를 의미한다.

상위 쿼리의 결과에 영향을 주지 않으면서 상세한 정보를 얻기 위해 사용됩니다. 쉽게 말하면, 한 쿼리 안에서 다른 쿼리를 실행하여 더 자세한 결과를 얻는 방식이라고 할 수 있습니다.

서브쿼리는 SQL 명령의 WHERE 구에서 주로 사용된다. WHERE 구는 SELECT, DELETE, UPDATE 구에서 사용할 수 있는데 이들 중 어떤 명령에서든 서브쿼리를 사용할 수 있다.

 

 

스칼라 값

 

서브쿼리를 사용할 때는 SELECT 명령이 어떤 값을 반환하는지 주의할 필요가 있다. 여러 가지 패턴 중에서도 다음과 같은 네 가지가 일반적인 서브쿼리 패턴이다.

-- 1. 하나의 값을 반환하는 패턴
SELECT MIN(a) FROM sample1;

-- 2. 복수의 행이 반환되지만 열은 하나인 패턴
SELECT no FROM sample1;

-- 3. 하나의 행이 반환되지만 열이 복수인 패턴
SELECT MIN(a), MAX(no) FROM sample1;

-- 4. 복수의 행, 복수의 열이 반환되는 패턴
SELECT no, a FROM sample1;

여기서 패턴 1은 다른 패턴과 달리 하나의 값을 반환한다. SELECT 명령이 하나의 값만 반환하는 것을 '스칼라 값을 반환한다'고 한다. 스칼라 값을 반환하는 SELECT 명령을 특별 취급하는 이유는 서브쿼리로서 사용하기 쉽기 때문이다.

 

 

서브쿼리 사용

 

 

1. DELETE의 WHERE 구에서 서브쿼리 사용

-- 괄호로 서브쿼리를 지정해 삭제
DELETE FROM sample1 WHERE a = (SELECT MIN(a) FROM sample1);

 

 

2. SELECT 구에서 서브쿼리 사용

-- SELECT 구에서 서브쿼리 사용
SELECT 
 (SELECT COUNT(*) FROM sample1) AS sq1,
 (SELECT COUNT(*) FORM sample2) AS sq2;
 
-- SELECT 구에서 서브쿼리 사용(Oracle의 경우)
SELECT 
 (SELECT COUNT(*) FROM sample1) AS sq1,
 (SELECT COUNT(*) FORM sample2) AS sq2 FROM DUAL;

Oracle 등 전통적인 데이터베이스 제품에서는 FROM를 생략할 수 없다. 이 때 Oracle에서는 다음과 같이 FROM DUAL로 지정하면 실행할 수 있다. DUAL은 시스템 쪽에서 데이터베이스에 기본으로 작성되는 테이블이다.

 

 

3. SET 구에서 서브쿼리 사용

-- SET 구에서 서브쿼리 사용
UPDATE sample1 SET a = (SELECT MAX(a) FROM sample1);

SET 구에서 서브쿼리를 사용할 경우에도 스칼라 값을 반환하도록 스칼라 서브쿼리를 지정할 필요가 있다. 

 

 

4. FROM 구에서 서브쿼리 사용

-- FROM 구에서 서브쿼리 사용
SELECT * FROM (SELECT * FROM sample1) AS sq;
SELECT * FROM (SELECT * FROM sample1) sq; -- Oracle의 경우

-- FROM 구에서 서브쿼리 사용(3단계)
SELECT * FROM (SELECT * FROM (SELECT * FROM sample1) sq1) sq2;

-- Oracle에서 LIMIT 구의 대체 명령
SELECT * FROM (
 SELECT * FROM sample1 ORDER BY a DESC
) sq
WHERE ROWNUM <= 2;

SELECT 명령 안에 SELECT 명령이 들어있는 구조를 '네스티드(nested) 구조', 또는 '중첩구조'나 '내부구조'라 부른다.

 

 

5. INSERT 명령과 서브쿼리

INSERT 명령과 서브쿼리를 조합해 사용할 수도 있다. INSERT 명령에는 VALUES 구의 일부로 서브쿼리를 사용하는 경우와,  VALUES 구 대신 SELECT 명령을 사용하는 두 가지 방법이 있다.

-- VALUES 구에서 서브쿼리 사용
INSERT INTO sample1 VALUES (
 (SELECT COUNT(*) FROM sample1),
 (SELECT COUNT(*) FROM sample2)
);

VALUES 구의 값으로 서브쿼리를 사용할 때, 서브쿼리는 스칼라 서브쿼리로 지정할 필요가 있다. 물론 자료형도 일치해야 한다.

 

-- SELECT 결과를 INSERT 하기
INSERT INTO sample1 SELECT 1, 2;

SELECT 결과를 INSERT하는 경우에는 SELECT 결괏값으로 1과 2라는 상수를 반환하므로, INSERT INTO sample1 VALUES (1, 2)의 경우와 같다.

INSERT SELECT 명령은 SELECT 명령의 결과를 INSERT INTO로 지정한 테이블에 전부 추가한다. SELECT 명령의 실행 결과를 클라이언트로 반환하지 않고 지정된 테이블에 추가하는 것이다. 이 때문에 데이터의 복사나 이동을 할 때 자주 사용하는 명령이다.

 

 

 

 

'DEVELOPMENT > SQL' 카테고리의 다른 글

[SQL] 테이블 작성/삭제/변경  (0) 2023.05.30
[SQL] 상관 서브쿼리  (0) 2023.05.30
[SQL] GROUP BY  (0) 2023.05.30
[SQL] 집계함수  (0) 2023.05.30
[SQL] CASE 문  (0) 2023.05.30