본문 바로가기

Language/MySQL

[MySQL] 상관 서브쿼리

EXISTS

[SYNTAX]
EXISTS (SELECT 명령)

 

EXISTS 술어를 사용하면 서브 쿼리가 반환하는 결괏값이 있는지를 조사할 수 있다.

예를 들어 서브쿼리를 사용해 검색할 때 '데이터가 존재하는지 아닌지' 판별하기 위해 조건 지정이 가능한데, 이 경우 EXISTS 술어를 사용해 조사할 수 있다.

위 두개의 테이블을 활용해서 sample552에 no열과 같은 값의 행이 있다면 '있음'으로, 없다면 '없음'으로 갱신한다.

 

없음의 경우, 행이 존재하지 않는 상태가 참이 되므로 이때는 NOT EXISTS를 사용한다.

NOT을 붙이는 것으로 값을 부정할 수 있다.

 

 

 

상관 서브쿼리

서브 쿼리에는 명령 안에 중첩 구조로 된 SELECT 명령이 존재한다.

update sample551 set a = '있음'
where exists (select * from sample552 where no2 = no);

UPDATE 명령(부모)에서 WHERE구에 괄호로 묶은 부분이 서브 쿼리(자식)가 된다.

부모 명령에서는 sample551을 갱신하고, 자식인 서브 쿼리에서는 sample552 테이블의 no2 열 값이 부모의 no 열 값과 일치하는 행을 검색한다.

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

 

delete from sample54 where a = (select min(a) from sample54);

이 DELETE 명령의 경우 상관 서브 쿼리가 아니다. 상관 서브쿼리가 아닌 단순한 서브 쿼리는 단독 쿼리로 실행이 가능하다.

하지만, 상관 서브 쿼리에서는 부모 명령과 연관되어 처리되기 때문에 서브쿼리 부분만을 따로 떼어내어 실행시킬 수 없다.

 

만약 sample551과 sample552 테이블의 열의 이름이 no로 동일하다면, 'WHERE no = no' 라 조건을 지정했을 때 에러가 발생한다. 

이러한 에러를 방지하기 위해 테이블명을 붙여주어 사용하면 된다.

update sample551 set a = '있음' 
where exists (select * from sample552
              where sample552.no2 = sample551.no);

이렇게 테이블명을 붙여줄 경우 열 이름이 같더라도 구별이 되므로 문제없이 실행이 가능하다.

 

 

IN

스칼라 값끼리 비교할 때는 = 연산자를 사용하지만, 집합을 비교할 때는 사용할 수 없다.

IN을 사용하면 집합 안에 값이 존재하는지 조사가 가능하다.

그래서 서브 쿼리를 사용할 때 IN을 통해 비교하는 경우도 많다.

[SYNTAX]
열명 IN (집합)

 

 

이외에도 집합 부분을 서브 쿼리로 지정할 수도 있다.

 

게다가 집합 안에 포함되어 있지 않은 경우를 검색하고 싶다면 NOT IN을 사용하면 된다.

 

 

집계 함수에서는 집합 안의 NULL을 무시하고 처리했다. IN에서는 집합 안에 NULL 값이 있어도 무시하지 않는다. 다만, NULL = NULL을 제대로 계산할 수 없으므로 IN을 사용해도 NULL값은 비교할 수 없다. 

NULL 값을 비교할 때는 IS NULL을 사용해야 한다.

또한 NOT IN의 경우, 집합 안에 NULL값이 있으면 설령 왼쪽 값이 집합 안에 포함되어 있지 않아도 참을 반환하지 않는다.

'Language > MySQL' 카테고리의 다른 글

[MySQL] 테이블 작성, 삭제, 변경  (0) 2022.11.22
[MySQL] 데이터베이스 객체  (0) 2022.11.22
[MySQL] 서브쿼리  (0) 2022.11.17
[MySQL] 그룹화 - GROUP BY  (0) 2022.11.15
[MySQL] COUNT 이외의 집계 함수  (0) 2022.11.11