상관 서브쿼리

유석현(SeokHyun Yu)·2022년 8월 14일
0

SQL

목록 보기
24/45
post-thumbnail

서론

서브쿼리를 사용해 DELETE 명령과 SELECT 명령을 결합할 수 있었다.

스칼라 서브쿼리가 사용하기 쉬운 서브쿼리란 것도 알았다.

이번 챕터에서는 서브쿼리의 일종인 '상관 서브쿼리'EXISTS 술어로 조합시켜서 서브쿼리를 사용하는 방법에 관해 알아보겠다.


1. EXISTS

서브쿼리를 사용해 검색할 때 '데이터가 존재하는지 아닌지' 판별하기 위해 조건을 지정할 수 있다.

이런 경우 EXISTS 술어를 사용해 조사할 수 있다.

EXISTS 의 용법을 자세히 설명하기 위해 다음과 같이 두 개의 샘플 테이블을 사용하겠다.

SELECT * FROM sample_table;

SELECT * FROM sample_table2;

sample_table에는 id 열에 1 에서 5 까지의 데이터가 저장되어 있다.

한편 sample_table2에는 3 과 5 가 저장되어 있다.

여기서 sample_table 의 a 열은 문자열형이지만 값은 모두 NULL이다.

이 열을 UPDATE로 갱신하려 한다.

지금부터 sample_table2에 id 열의 값과 같은 행이 있다면 '있음'이라는 값으로, 행이 없으면 '없음'이라는 값으로 갱신하도록 하겠다.

몇 가지 갱신 방법이 있지만, 여기서는 WHERE 구에 조건을 지정해 '있음'으로 갱신하는 경우와 '없음'으로 갱신하는 경우로 나누어 처리하겠다.

'있음'의 경우, 행이 존재하는 경우에 대해 으로 설정한다.

즉, 다음과 같이 EXISTS를 사용하면 조건에 맞는 행을 갱신할 수 있다.

UPDATE sample_table AS st SET a='있음' WHERE 
	EXISTS (SELECT * FROM sample_table2 AS st2 WHERE st2.id = st.id);

EXISTS 술어에 서브쿼리를 지정하면 서브쿼리가 행을 반환할 경우에 참을 돌려준다.


2. NOT EXISTS

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

UPDATE sample_table AS st SET a='없음' WHERE 
	NOT EXISTS (SELECT * FROM sample_table2 AS st2 WHERE st2.id = st.id);

이처럼 서브쿼리를 이용해 다른 테이블의 상황을 판단하고 UPDATE로 갱신할 수 있다.

여기서는 UPDATE 명령을 예제로 다루었지만 SELECT 명령이나 DELETE 명령에서도 EXISTS 를 사용하여 명령을 실행할 수 있다.


3. 상관 서브쿼리

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

지금부터 '있음'으로 갱신하는 UPDATE 명령을 다시 살펴보겠다.

UPDATE sample_table AS st SET a='있음' WHERE 
	EXISTS (SELECT * FROM sample_table2 AS st2 WHERE st2.id = st.id);

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

부모 명령에서는 sample_table을 갱신한다.

자식인 서브쿼리에서는 sample_table2 테이블의 id 열 값이 부모의 id 열 값과 일치하는 행을 검색한다.

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


4. IN

스칼라 값끼리 비교할 때는 = 연산자를 사용한다.

다만 집합을 비교할 때는 사용할 수 없다.

IN을 사용하면 집합 안의 값이 존재하는지를 조사할 수 있다.

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

더 자세한 내용은 지금부터 sample_table과 sample_table2 테이블을 사용해 설명하겠다.

sample_table2 에는 3 과 5 라는 값이 존재한다.

서브쿼리를 사용하지 않고 WHERE 구로 간단하게 처리한다면 다음과 같이 조건을 붙일 수 있겠다.

WHERE id=3 OR id=5;

IN 에서는 오른쪽에 집합을 지정한다.

왼쪽에 지정된 값과 같은 값이 집합 안에 존재하면 참을 반환한다.

집합은 상수 리스트괄호로 묶어 기술한다.

앞의 WHERE 조건식을 IN을 사용하도록 수정하면 다음과 같다.

SELECT * FROM sample_table WHERE id IN (3, 5);

한편, 집합 부분은 서브쿼리로도 지정할 수 있다.

상수 리스트 부분을 서브쿼리로 바꾸어 보겠다.

SELECT * FROM sample_table WHERE id IN (SELECT id FROM sample_table2);

이 같은 경우 서브쿼리는 스칼라 서브쿼리가 될 필요는 없다.

IN에는 집합을 지정할 수 있기 때문에 행이 여러 개 반환되는 서브쿼리도 사용할 수 있다.

단, 열이 여러 개 반환되는 서브쿼리는 사용할 수 없다.

profile
Backend Engineer

0개의 댓글