ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • SQL 상관 서브쿼리
    Database 2021. 4. 19. 13:27
    728x90

    상관 서브 쿼리

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

    상관 서브 쿼리의 경우 부모 명령과 관계를 맺고 있기 때문에 상관 서브 쿼리는 단독 쿼리 즉, 혼자서는 실행을 할 수 없다.

    설명만 보면 이해가 가지 않으므로 아래 예시와 함께 이해해보도록 하자!

    앞서 DELETE 명령에 대한 서브 쿼리이다.

    # 상관 서브쿼리 X
    DELETE FROM ttt_set WHERE A = (SELECT MIN(A) FROM ttt_set);
    SELECT MIN(A) FROM ttt_set
    
    # 상관 서브쿼리 O
    UPDATE 테이블명1 SET A(열1) = "TEST" WHERE EXISTS (SELECT * FROM 테이블명2 WHERE 열2 =열1);
    SELECT * FROM 테이블명2 WHERE 열2 =열1; => 에러 열2가 불명확하다.
    

    DELETE 명령과 서브 쿼리의 경우 서브 쿼리를 단독으로 실행할 수 있다.

    서브 쿼리가 단독으로 실행될 때 부모가 되는 명령에 대한 정보를 필요로 하지 않기 때문이지 않을까 싶다. 

    반면 UPDATE 명령과 상관 서브 쿼리의 경우 부모(명령), 자식(서브 쿼리)의 특정 관계가 있기에 상관 서브 쿼리를 단독으로 실행할 수 없다.

    서브 쿼리가 단독으로 실행하기 위해서는 부모 명령의 테이블에 대한 정보를 필요로 하기 때문에 단독으로 실행되지 않는다.

    부모, 자식 관계를 찾기 어려운 명령에 대해서는 서브 쿼리를 단독으로 실행해보는 것으로 상관 서브 쿼리임을 알 수 있지 않을까 싶다.


    UPDATE + EXISTS + 상관 서브쿼리

    UPDATE 테이블명1 SET A(열1) = NULL WHERE EXISTS (SELECT * FROM 테이블명2 WHERE 열2 =열1);

    EXISTS 술어를 서브 쿼리와 함께 사용하는 예시를 보자.

    EXISTS는 단어 뜻 그대로 반환하는 결괏값이 있는지 없는지 확인을 할 수 있다. 

    NOT EXISTS 또한 상황에 따라 사용이 가능하다.

    EXISTS와 서브 쿼리를 함께 사용할 때 서브 쿼리의 반환하는 값을 확인하는 용도로 사용되는데 이때 서브 쿼리는 반드시 스칼라 서브 쿼리일 필요는 없다. 단지 특정 조건에 맞는 행(값)이 있는지 없는지의 여부만 판달할 뿐이기 때문에 반환되는 행의 개수는 중요하지 않다.

    특정 조건에 맞는 행이 있을 경우 참, 없을 경우 거짓이다. 


    EXISTS 예시를 들기 위해 두 테이블을 이용해보도록 하자.

    products의 discount_id 열 => 현재 모든 셀의 값은 1 인 상태이다.

    ttt_set의 id 열 => EXISTS 조건으로 사용하도록 한다.


    EXISTS (상관 서브 쿼리 = 거짓)

    현재 ttt_set 테이블의 id = 1인 값은 존재하지 않는다. 따라서 discount_id를 NULL로 갱신하지 않는다.

    상관 서브 쿼리 이므로 단독 서브 쿼리로도 실행이 된다.

    update products set discount_id = NULL where 
    exists (select id from ttt_set where id = 1);


    EXISTS (상관 서브쿼리 = 참)

    현재 ttt_set 테이블의 id = 3인 값 존재한다. 따라서 discount_id를 NULL로 갱신된 것을 확인할 수 있다.


    테이블명 붙이기

    UPDATE 테이블명1 SET A(열1) = NULL WHERE EXISTS (SELECT * FROM 테이블명2 WHERE 열2 =열1);

    위 예시에서 열 2와 열 1은 discount_id와 id로 같지 않았다.

    만약 열명이 둘 다 id id로 같으면 어떻게 될까?

    표준 SQL에서는 잘 동작하지 않는다. (MySQL에서는 각각 테이블명 1. 열 1, 테이블명 2. 열 2로 인식하여 열명이 동일해도 에러가 발생하지 않는다고 한다.)

    따라서 열이 어느 테이블의 열인지 명시해줘야 할 필요가 있다.

    위의 예제를 열 1, 열 2 열명이 같을 때로 바꿔보자면 아래와 같이 바꿀 수 있다. 

    UPDATE product SET A = NULL WHERE EXISTS (SELECT * FROM reviews WHERE reviews.A =product.A);

    MySQL에서는 열명을 명시해주지 않아도 위와 같이 인식하기 때문에 에러가 발생하지 않는다.  

     

    출처 :

    SQL 첫걸음/ 아사이 아츠시 지음/ 한빛미디어

    728x90

    'Database' 카테고리의 다른 글

    SQL 테이블 작성, 삭제, 변경  (0) 2021.04.27
    SQL 데이터베이스 객체  (0) 2021.04.25
    SQL 서브쿼리_2  (0) 2021.04.14
    SQL 서브쿼리_1  (0) 2021.04.09
    SQL GROUP BY  (0) 2021.04.09
Designed by Tistory.