[SQL] 상관 서브쿼리

가비·2020년 12월 24일
1

[SQL]

목록 보기
5/13

상관 서브쿼리란 ? 부모 명령과 자식인 서브쿼리가 특정 관계를 맺는 것을 상관 서브쿼리라 한다.

EXISTS

mysql> SELECT * FROM sample551;
+------+------+
| no   | a    |
+------+------+
|    1 | NULL |
|    2 | NULL |
|    3 | NULL |
|    4 | NULL |
|    5 | NULL |
+------+------+
5 rows in set (0.00 sec)

mysql> SELECT * FROM sample552;
+------+
| no2  |
+------+
|    3 |
|    5 |
+------+
2 rows in set (0.00 sec)

# sample552에 no 열의 값과 같은 행이 있다면 '있음'으로 갱신
mysql> UPDATE sample551 SET a = '있음' WHERE
    -> EXISTS (SELECT * FROM sample552 WHERE no2 = no);
Query OK, 2 rows affected (0.00 sec)
Rows matched: 2  Changed: 2  Warnings: 0

mysql> SELECT * FROM sample551;
+------+--------+
| no   | a      |
+------+--------+
|    1 | NULL   |
|    2 | NULL   |
|    3 | 있음    |
|    4 | NULL   |
|    5 | 있음    |
+------+--------+
5 rows in set (0.00 sec)
  • EXISTS를 사용하는 경우 서브쿼리가 스칼라 값을 반환하지 않아도 된다.
    👉 서브쿼리가 반환하는 결과값이 있는지를 확인하여 있으면 참 없으면 거짓을 반환하기 때문

NOT EXISTS

mysql> UPDATE sample551 SET a = '없음' WHERE
    -> NOT EXISTS (SELECT * FROM sample552 WHERE no2 = no);
Query OK, 3 rows affected (0.00 sec)
Rows matched: 3  Changed: 3  Warnings: 0

mysql> SELECT * FROM sample551;
+------+--------+
| no   | a      |
+------+--------+
|    1 | 없음    |
|    2 | 없음    |
|    3 | 있음    |
|    4 | 없음    |
|    5 | 있음    |
+------+--------+
5 rows in set (0.00 sec)
  • '없음'의 경우 행이 존재하지 않는 상태가 참이 되므로 NOT을 붙여 값을 부정한다.

상관 서브쿼리

  • 상관 서브쿼리는 부모 명령과 연관되어 처리되기 때문에 단독으로 실행할 수 없다.
    👉 상관 서브쿼리가 아닌 단순한 서브쿼리는 단독 쿼리로 실행할 수 있다.

✔️ 두 열이 모두 같은 이름을 가진다면 어떻게 될까?

# WHERE no = no
❕ MySQL에서는 WHERE sample552.no = sample552.no가 되어 항상 참이 된다.
👉 결과적으로 sample551의 모든 행은 a 열 값이 '있다'로 갱신된다.

테이블명 붙이기

mysql> UPDATE sample551 SET a = '있음' WHERE
    -> EXISTS (SELECT * FROM sample552 WHERE sample552.no2 = sample551.no);
Query OK, 0 rows affected (0.00 sec)
Rows matched: 2  Changed: 0  Warnings: 0

IN

열명 IN(집합)
mysql> SELECT * FROM sample551 WHERE no IN(3,5);
+------+--------+
| no   | a      |
+------+--------+
|    3 | 있음    |
|    5 | 있음    |
+------+--------+
2 rows in set (0.00 sec)

# 서브쿼리로 지정
mysql> SELECT * FROM sample551 WHERE no IN
    -> (SELECT no2 FROM sample552);
+------+--------+
| no   | a      |
+------+--------+
|    3 | 있음    |
|    5 | 있음    |
+------+--------+
2 rows in set (0.00 sec)
  • IN을 사용하면 집합 안의 값이 존재하는지 조사할 수 있고 서브쿼리를 비교할 수 있다.
  • 오른쪽에 집합을 지정하고 왼쪽에 지정된 값과 같은 값이 집합 안에 존재하면 참을 반환한다.
    👉 NOT IN으로 지정하면 값이 포함되어 있지 않을 경우 참
  • 스칼라 서브쿼리가 아니어도 되지만 여기서 언급한 패턴 3, 4로는 비교할 수 없다.
    👉 IN의 왼쪽에 하나의 열만 지정되어 있기 때문

IN과 NULL

  • IN에서는 집합안에 NULL 값이 있어도 무시하지는 않지만 NULL = NULL을 계산할 수 없으므로 IN을 사용해도 NULL 값은 비교할 수 없다.
    👉 NULL을 비교할 때는 IS NULL !
  • NOT IN의 경우 왼쪽 값이 집합 안에 포함되어 있지 않아도 참을 반환하지 않는다.

✔️ MySQL에서 집합에 NULL이 포함된 경우

  • IN 왼쪽 값이 집합에 포함되어 있으면 참, 그렇지 않으면 NULL 반환
  • NOT IN 왼쪽 값이 집합에 포함되어 있으면 거짓, 그렇지 않으면 NULL 반환
    👉 NOT IN의 경우 결국 결괏값은 0건이 된다.
  • 왼쪽의 값이 NULL인 경우 비교할 수 없으므로 NULL 반환

0개의 댓글