자격증/SQLD

[SQL 첫걸음] 24강. 상관 서브쿼리

동호다찌 2022. 4. 4. 09:28

상관 서브쿼리

서브쿼리의 일종을 상관 서브쿼리라 합니다. 더 자세한 정의는 상관 서브쿼리에서 확인하겠습니다.

1. EXISTS

서브쿼리를 사용해 검색할 때 데이터 존재여부를 판별하기 위해 조건을 지정할 수 있습니다.

  • 이런 경우 EXISTS 술어를 사용할 수 있습니다.
  • 이때 EXISTS 술어는 단지 반환된 행이 있는지를 확인해보고 값의 있으면 참(True), 없으면 거짓(False)을 반환하므로 굳이 스칼라 서브쿼리일 필요는 없습니다.
  • sample551과 sample552에 대해 no=no2인 행의 값을 '있음'으로 수정하려 할 때 다음과 같이 EXISTS를 사용하면 조건에 맞는 행을 갱신할 수 있다.
UPDATE sample551 SET a="있음" WHERE EXISTS (SELECT * FROM sample552 WHERE no2=no);


2. NOT EXISTS

NOT EXISTS를 통해 반대의 경우도 반환할 수 있다.

UPDATE sample551 SET a="없음" WHERE NOT EXISTS (SELECT * FROM sample552 WHERE no2=no);


3. 상관 서브쿼리

UPDATE sample551 SET a = '있음' WHERE
    EXISTS (SELECT * FROM sample552 WHERE no2 = no); 
  • 위에 쿼리처럼 UPDATE명령(부모)와 WHERE구의 서브쿼리(자식)이 특정 관계를 맺는 것을
    '상관 서브쿼리'라고 부른다.
  • 단순 서브쿼리와 다르게 상관 서브쿼리의 서브쿼리는 단독 실행이 안된다.
DELETE FROM sample54 WHERE a = (SELECT a FROM (SELECT MIN(a) AS a FROM sample54) AS x);
  • DELETE에서 사용한 다음과 같은 명령문은 상관 서브쿼리가 아닙니다. 해당 서브쿼리를 단독 쿼리로 실행할 수 있기 때문입니다.
  • 상관 서브쿼리의 경우 부모 명령과 연관되어 처리되기 때문에 서브쿼리 부분만을 따로 떼어내어 실행시킬 수 없습니다.

3-1. 테이블명 붙이기

SELECT * FROM sample552 WHERE no2=no → no2불분명 에러
  • 만약에 테이블 sample552의 열 이름이 no2가 아닌 no였다면 sample551의 열과 중복됩니다.
  • 이렇게 해당 열의 이름이 중복되어 어떤 테이블에 속해있는 열인지 구분이 되지 않을 경우 오류가 발생합니다.
  • 이런 경우 점(.)을 사용해 앞 부분에 해당 열이 속한 테이블 명을 입력해서 구분지을 수 있습니다. 명령문 예시는 아래와 같습니다.

이럴 때는 sample551.no, sample552.no처럼 명시적으로 지정해주면 된다.

SELECT * FROM sample552,sample551 WHERE sample552.no2 = sample551.no

또한 아래처럼도 사용할 수 있습니다.

UPDATE sample551 SET a = '있음' WHERE EXISTS (
    SELECT * FROM sample552 WHERE sample552.no = sample551.no
);

4. IN

스칼라 값끼리 비교할 때는 =연산자를 쓰지만, 집합을 비교할 때는 IN을 통해 비교한다.

SELECT * FROM sample552 WHERE no2 = no;
  • 위 쿼리는 오류를 불러온다 하지만 IN을 통해 아래와 같이 바꿀 수 있다.
SELECT * FROM sample551 WHERE no IN (SELECT no2 FROM sample552);
  • 집계함수에서는 NULL값을 무시하고 처리하지만, IN에서는 NULL=NULL을 제대로 처리할 수 없으므로 IS NULL을 사용해 비교해야한다.
  • 또한 NOT IN은 집합 안에 NULL이 있으면 참/거짓이 아닌 0이나 NULL등을 반환한다.