1. 서브쿼리

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

서브쿼리를 지정하는 방법은 간단하게 SELECT 쿼리를 괄호로 묶어서 SELECT / FROM / WHERE 구 등에서 사용할 수 있습니다.

  1. 스칼라 값

서브쿼리를 다른 구에서 사용하는 것을 설명하기전에 스칼라 값이라는 것에 대해 설명해 보겠습니다.

서브쿼리를 사용할 때는 그 쿼리가 어떤 값을 반환하는지 주의할 필요가 있습니다. SELECT 쿼리를 실행 시 여러가지 패턴들이 나올수 있지만 일반적인 패턴에 대해 아래 표에 설명하겠습니다.


#

쿼리

설명

1

SELECT MIN(컬럼) FROM 테이블명

하나의 값을 반환

2

SELECT 컬럼 FROM 테이블명

하나의 컬럼에 복수의 레코드

3

SELECT MIN(컬럼1), MAX(컬럼2) FROM 테이블명

하나의 레코드 복수의 컬럼

4

SELECT 컬럼1, 컬럼2 FROM 테이블명

복수의 레코드 복수의 컬럼

[표 11. SELECT 쿼리 실행 시 반환되는 일반적인 패턴]


[표 11]에서 보면 다른 패턴과 다르게 1번 패턴은 하나의 값만을 반환합니다. 이렇게 SELECT 쿼리가 하나의 값만 반환하는 것을 단일값 또는 스칼라 값 이라고 합니다.

  1. WHERE 구에서 사용

WHERE 구에서 서브쿼리는 조건식에서 변수와 같이 사용이 가능합니다.

예를 들어 하나의 테이블에서 특정 컬럼의 최소 값을 찾아서 해당 레코드를 삭제해야 하는 경우를 생각해 보겠습니다. 이때 테이블에 데이터가 적고 한눈에 확인이 가능한 정도라면 눈으로 찾을 수 있겠지만 보통은 그렇게 찾을 수 없습니다. 이때 서브쿼리를 활용한다면 보다 쉽게 쿼리 작성이 됩니다.

먼저 서브쿼리는 해당 컬럼의 최소값을 찾을 것입니다.


1

SELECT MIN(컬럼) FROM 테이블;

[표 12. 최소값을 찾는 서브쿼리]


[표 12]와 같이 서브쿼리 작성이 되었다면 실제 레코드 삭제 부분에 적용해 보겠습니다.


1

DELETE FROM 테이블 WHERE 컬럼 = (SELECT MIN(컬럼) FROM 테이블);

[표 13. 최소값을 가진 레코드를 삭제하는 쿼리]


생각보다 간단하죠? 서브쿼리의 스칼라값을 조건식의 변수로 지정하여 사용하는 방법입니다. 하지만 데이터베이스별로 해당 쿼리가 실행이 되지 않을 수 있습니다.

동일한 테이블 내에서 추가나 갱신할 경우 서브쿼리가 제한될 수 있으니 사용하시는 데이터베이스 메뉴얼을 확인하길 바랍니다.

  1. SELECT 구에서 사용

SELECT 구에서 서브쿼리를 지정할 때는 스칼라 서브쿼리가 필요합니다.


1

SELECT

(SELECT COUNT(*) FROM 테이블명) AS sq;

[표 14. SELECT 구에서 서브쿼리 사용 방법]


[표 14]에서는 주의할 점이 있습니다. 서브쿼리가 아닌 상부의 SELECT 구에 FROM 구가 없다는 것입니다. 이것이 MySQL에서는 실행이 되지만 ORACLE과 같이 데이터 베이스에 따라 실행이 되지 않을 수 있습니다. 그럴때는 FROM 구를 정의해 줘야 합니다. 예를 들어 Oracle을 보면 FROM DUAL로 지정하면 실행할 수 있습니다. 다른 데이터베이스를 사용하신다면 메뉴얼을 확인하길 바랍니다.

  1. SET 구에서 사용

UPDATE의 SET구에서도 서브쿼리를 사용할 수 있습니다. SET 구에서도 서브쿼리를 사용할 때 스칼라 서브쿼리를 지정할 필요가 있습니다.


1

UPDATE 테이블 SET 컬럼 = (SELECT MAX(컬럼) FROM 테이블);

[표 15. SET구에서 서브쿼리 사용 방법]

  1. FROM 구에서 사용

지금까지는 FROM 구에서 테이블명을 지정하였습니다. 하지만 FROM 구에도 서브쿼리를 지정할 수 있습니다. 위에서는 서브쿼리를 사용할 때 스칼라 서브쿼리를 사용하라고 했었지만 FROM 구에서 사용되는 서브쿼리는 스칼라 값을 반환하지 않아도 됩니다.


1

SELECT * FROM (SELECT * FROM 테이블2);

[표 16. FROM 구에서 서브쿼리 사용 방법]


구조가 조금 특이하게 SELECT 쿼리 안에 SELECT 쿼리가 들어 있는 것처럼 보입니다. 이런것은 ‘네스티드 구조' 또는 ‘중첩구조', ‘내표 구조'라고 합니다.

[표 16]은 2단계 중첩 구조입니다. 중첩 구조는 몇단계를 구성해도 상관은 없습니다. 하지만 3단계 이상은 추천하지 않습니다.

  1. INSERT에서 사용

INSERT 쿼리에서도 VALUES 구의 일부로 서브쿼리를 사용할 수 있고, VALUE 구 대신 SELECT 쿼리를 사용하는 두가지 방법이 있습니다.


첫째, VALUES 구의 일부로 사용될 때

이때는 서브쿼리는 스칼라 서브쿼리를 사용해야 하고 자료형도 일치해야 합니다.


1

INSERT INTO 테이블 VALUES (

  (SELECT COUNT(*) FROM 테이블2), ...

);

[표 17. VALUES 구의 일부로 서브쿼리 사용 방법]


둘째, VALUES 구 대신 서브쿼리가 사용될 때

흔히 ‘INSERT SELECT’라 불리는 쿼리입니다. INSERT SELECT 쿼리는 SELECT 쿼리의 결과를 INSERT INTO로 지정된 테이블에 전부 추가합니다. 여기서 주의할 것은 SELECT 쿼리에서 반환하는 컬럼의 수와 자료형이 INSERT할 테이블과 일치해야 합니다. 그래서 INSERT SELECT는 테이터의 복사나 이동을 할 때 자주 사용됩니다.


1

INSERT INTO 테이블 SELECT * FROM 테이블2;

[표 18. VALUES 구 대신 SELECT 쿼리를 사용하는 방법]


저작자 표시 비영리 동일 조건 변경 허락
신고

+ Recent posts

티스토리 툴바