본문 바로가기

Language/MySQL

[MySQL] 서브쿼리

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

[SYNTAX]
( SELECT 명령 )

 

서브 쿼리는 SQL 명령문 안에 지정하는 하부 SELECT 명령으로 괄호로 묶어 지정한다.

특히 서브 쿼리는 SQL 명령의 WHERE구에서 주로 사용된다. 

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

 

DELETE의 WHERE구에서 서브 쿼리 사용하기

 

서브 쿼리를 사용해서 최솟값을 가지는 행을 삭제할 수 있지만, MySQL에서는 실행할 수 없다.

데이터를 추가하거나 갱신할 경우 동일한 테이블을 서브 쿼리에서 사용할 수 없도록 되어있기 때문이다.

에러를 발생하지 않고 실행하려면 인라인 뷰로 임시 테이블을 만들도록 처리하면 가능하다.

 

 

 

스칼라 값

서브쿼리를 사용할 때는 그 SELECT 명령이 어떤 값을 반환하는지 주의할 필요가 있는데, 그중 하나의 값만 반환하는 것을 '스칼라 값을 반환한다'라고 한다.

서브 쿼리의 패턴 1 ) 하나의 값을 반환하는 패턴 (스칼라 값 반환)

 

서브쿼리의 패턴 2 ) 복수의 행이 반환되지만 열은 하나인 패턴

 

서브 쿼리의 패턴 3 ) 하나의 행이 반환되지만 열이 복수인 패턴

 

서브 쿼리의 패턴 4 ) 복수의 행, 복수의 열이 반환되는 패턴

 

스칼라 값을 반환하는 SELECT 명령은 서브 쿼리로서 사용하기 쉽다.

통상적으로 특정한 두 가지가 서로 동일한지 여부를 비교할 때는 서로 단일한 값으로 비교한다. 

WHERE구에서 스칼라 값을 반환하는 서브 쿼리는 = 연산자로 비교할 수 있다는 뜻이다.

스칼라 값을 반환하는 서브쿼리를 '스칼라 서브쿼리'라 부르기도 한다.

 

 

SELECT 구에서 서브 쿼리 사용하기

서브 쿼리는 WHERE구 이외에도 SELECT구, UPDATE의 SET구 등 다양한 구 안에 지정할 수 있다.

문법적으로 서브 쿼리는 '하나의 항목'으로 취급한다. 단, 문법적으로는 문제없지만 실행하면 에러가 발생하는 경우가 종종 있는데, 이는 스칼라 값의 반환 여부에 따라 생기는 현상으로, 서브 쿼리를 사용할 때는 스칼라 서브 쿼리로 되어있는지 확인해야 한다.

 

MySQL에서는 from 구가 없어도 쿼리가 실행이 되지만, MySQL을 제외한 다른 데이터베이스 제품에서는 from구를 생략할 수 없다. 이때 Oracle에서는 from dual로 지정하면 실행이 가능하다. dual은 시스템 쪽에서 데이터베이스에 기본으로 작성되는 테이블이다.

 

 

SET 구에서 서브쿼리 사용하기

UPDATE의 SET구에서 서브 쿼리를 사용해 데이터 갱신이 가능하다.

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

 

 

FROM 구에서 서브쿼리 사용하기

FROM구에서 서브쿼리를 기술할 경우 SELECT구나 SET구처럼 스칼라 값을 반환하지 않아도 상관없다.

이처럼 SELECT 명령 안에 SELECT 명령이 있는 듯 보이는 것을 '네스티드(nested) 구조' 또는 '중첩 구조', '내포 구조'라 한다.

중첩 구조는 몇 단계로든 구성할 수 있다.

 

 

INSERT 명령과 서브쿼리

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

- VALUES 구에서 서브쿼리 사용

 

- SELECT 결과 INSERT

흔히 'INSERT SELECT'라 불린다.

예시에서의 SELECT 1, 2 가 VALUES(1, 2)와 같다.

이때 SELECT 명령이 반환하는 값이 꼭 스칼라 값일 필요는 없다.

SELECT가 반환하는 열 수와 자료형이 INSERT 할 테이블과 일치하기만 하면 된다.

그래서 테이블의 데이터 복사나 이동을 할 때 INSERT SELECT 명령을 자주 사용한다.

insert into sample542 select * from sample543;

'Language > MySQL' 카테고리의 다른 글

[MySQL] 데이터베이스 객체  (0) 2022.11.22
[MySQL] 상관 서브쿼리  (0) 2022.11.20
[MySQL] 그룹화 - GROUP BY  (0) 2022.11.15
[MySQL] COUNT 이외의 집계 함수  (0) 2022.11.11
[MySQL] 행 개수 구하기 - COUNT  (1) 2022.11.04