[SQL] 서브쿼리

가비·2020년 12월 23일
0

[SQL]

목록 보기
4/13

서브쿼리란? SQL 명령문 안에 지정하는 하부 SELECT 명령으로 부수적인 질의를 말한다.

서브쿼리

  • WHERE 구에서 주로 사용된다.
  • SELECT, FROM, WHERE 구 등 SELECT 명령의 각 구를 기술할 수 있다.

DELETE의 WHERE 구에서 서브쿼리

mysql> SELECT * FROM sample54;
+------+------+
| no   | a    |
+------+------+
|    1 |  100 |
|    2 |  900 |
|    3 |   20 |
|    4 |   80 |
+------+------+
4 rows in set (0.01 sec)

# a 열의 최솟값 검색
mysql> SELECT MIN(a) FROM sample54;
+--------+
| MIN(a) |
+--------+
|     20 |
+--------+
1 row in set (0.00 sec)

# 괄호로 서브쿼리를 지정하여 삭제
mysql> DELETE FROM sample54 WHERE a = (SELECT a FROM(SELECT  MIN(a) AS a FROM sample54) AS x);
Query OK, 1 row affected (0.00 sec)

mysql> SELECT * FROM sample54;
+------+------+
| no   | a    |
+------+------+
|    1 |  100 |
|    2 |  900 |
|    4 |   80 |
+------+------+
3 rows in set (0.01 sec)
  • 데이터를 추가하거나 갱신할 경우 동일한 테이블을 서브쿼리에서 사용할 수 없기 때문에 인라인 뷰로 임시 테이블을 만들도록 처리한다.

클라이언트 변수 사용

mysql> set @a = (SELECT MIN(a) FROM sample54);
Query OK, 0 rows affected (0.00 sec)

mysql> DELETE FROM sample54 WHERE a = @a;
Query OK, 1 row affected (0.00 sec)

mysql> SELECT * FROM sample54;
+------+------+
| no   | a    |
+------+------+
|    1 |  100 |
|    2 |  900 |
+------+------+
2 rows in set (0.00 sec)

스칼라 값

# 일반적인 서브쿼리 패턴

1. 하나의 값을 반환하는 패턴 👉 '단일 값'을 '스칼라 값' 이라고 한다.
mysql> SELECT MIN(a) FROM sample54;
+--------+
| MIN(a) |
+--------+
|    100 |
+--------+
1 row in set (0.00 sec)

2. 복수의 행이 반환되지만 열은 하나인 패턴
mysql> SELECT no FROM sample54;
+------+
| no   |
+------+
|    1 |
|    2 |
+------+
2 rows in set (0.00 sec)

3. 하나의 행이 반환되지만 열이 복수인 패턴
mysql> SELECT MIN(a), MAX(no) FROM sample54;
+--------+---------+
| MIN(a) | MAX(no) |
+--------+---------+
|    100 |       2 |
+--------+---------+
1 row in set (0.00 sec)

4. 복수의 행, 복수의 열이 반환되는 패턴
mysql> SELECT no, a FROM sample54;
+------+------+
| no   | a    |
+------+------+
|    1 |  100 |
|    2 |  900 |
+------+------+
2 rows in set (0.00 sec)
  • 스칼라 값을 반환하는 SELECT 명령은 서브쿼리로 사용하기 쉽다.
  • WHERE 구에서 스칼라 값을 반환하는 서브쿼리는 = 연산자로 비교할 수 있다.
  • 스칼라 서브쿼리는 WHERE 구에 사용할 수 있으므로 집계함수를 사용한 결과를 조건식으로 사용할 수 있다.

SELECT 구에서 서브쿼리

mysql> SELECT
    -> (SELECT COUNT(*) FROM sample51) AS sq1,
    -> (SELECT COUNT(*) FROM sample54) AS sq2;
+------+------+
| sq1  | sq2  |
+------+------+
|    5 |    2 |
+------+------+
1 row in set (0.01 sec)
  • 문법적으로 문제없지만 에러가 발생하는 경우 스칼라 서브쿼리로 되어있는지 확인해야 한다.

SET 구에서 서브쿼리

mysql> UPDATE sample54 SET a = (SELECT a FROM(SELECT MAX(a) AS a FROM sample54) AS x);
Query OK, 1 row affected (0.00 sec)
Rows matched: 2  Changed: 1  Warnings: 0

mysql> SELECT * FROM sample54;
+------+------+
| no   | a    |
+------+------+
|    1 |  900 |
|    2 |  900 |
+------+------+
2 rows in set (0.00 sec)

FROM 구에서 서브쿼리

mysql> SELECT * FROM (SELECT * FROM sample54) sq;

# AS 키워드 사용
mysql> SELECT * FROM (SELECT * FROM sample54) AS sq;
+------+------+
| no   | a    |
+------+------+
|    1 |  900 |
|    2 |  900 |
+------+------+
2 rows in set (0.00 sec)

# 3단계 중첩구조 예시 
mysql> SELECT * FROM (SELECT * FROM (SELECT * FROM sample54) sq1) sq2;
+------+------+
| no   | a    |
+------+------+
|    1 |  900 |
|    2 |  900 |
+------+------+
2 rows in set (0.00 sec)
  • SELECT 안에 SELECT 명령이 들어 있는 이러한 구조를 '네스티드(nested) 구조' 또는 중첩구조나 내포구조라 부른다.
  • FROM 구에서는 테이블이나 서브쿼리에 별명을 붙일 수 있다.
  • 중첩구조는 여러 단계로 구성할 수 있다.

INSERT와 서브쿼리

VALUES 구에서 서브쿼리 사용

mysql> INSERT INTO sample541 VALUES (
    -> (SELECT COUNT(*) FROM sample51),
    -> (SELECT COUNT(*) FROM sample54)
    -> );
Query OK, 1 row affected (0.00 sec)

mysql> SELECT * FROM sample541;
+------+------+
| a    | b    |
+------+------+
|    5 |    2 |
+------+------+
1 row in set (0.00 sec)
  • 스칼라 서브쿼리로 지정해야 하고 자료형도 일치해야 한다.

INSERT SELECT

mysql> SELECT * FROM sample541;
+------+------+
| a    | b    |
+------+------+
|    5 |    2 |
+------+------+
1 row in set (0.00 sec)

mysql> INSERT INTO sample541 SELECT 1,2;
Query OK, 1 row affected (0.02 sec)
Records: 1  Duplicates: 0  Warnings: 0

mysql> SELECT * FROM sample541;
+------+------+
| a    | b    |
+------+------+
|    5 |    2 |
|    1 |    2 |
+------+------+
2 rows in set (0.00 sec)
  • SELECT 값이 스칼라 값이 아니여도 된다.
    ! but SELECT가 반환하는 열 수와 자료형은 일치해야 한다.
  • INSERT INTO로 지정한 테이블에 전부 추가한다.
    👉 데이터의 복사나 이동에 자주 사용된다.

0개의 댓글