솜이의 데브로그

23,24강 ) 서브쿼리, 상관 서브쿼리 본문

CS/Database

23,24강 ) 서브쿼리, 상관 서브쿼리

somsoming 2021. 11. 14. 23:15

Reference : SQL 첫걸음

 

23강 ) 서브쿼리

  • 서브쿼리는 SQL 명령문 안에 지정하는 하부 SELECT 명령으로 괄호로 묶어 지정한다.
  • 서브쿼리는 SQL 명령의 WHERE 구에서 주로 사용된다.

 

 

1. DELETE의 WHERE 구에서 서브쿼리 사용하기

 

Ex) 최솟값을 가지는 행 삭제하기

DELETE FROM sample54 WHERE a = (SELECT MIN(a) FROM sample54);

SELECT * FROM sample54;

서브쿼리를 사용하여 DELETE와 SELECT를 결합할 수 있다.

괄호 안의 서브쿼리부분을 먼저 실행 후 DELETE 명령 실행

 

 

 

2. 스칼라 값

 

SELECT 명령이 하나의 값만을 반환하는 것을 '스칼라 값을 반환한다'라고 한다.

스칼라 값을 반환하도록 SELECT 명령을 작성하고자하면 SELECT 구에서 단일 열을 지정한다.

 

DELETE FROM sample54 WHERE a=(SELECT MIN(a) FROM sample54);

위에서 서브쿼리 부분은 스칼라 값을 반환하는 select 명령으로 되어 있으므로 = 연산자를 사용해 열 a의 값과 비교한다.

 

★ = 연산자를 사용하여 비교할 경우에는 스칼라 값끼리 비교해야한다.

 

스칼라 값을 반환하는 서브쿼리를 '스칼라 서브쿼리'라고 한다.

HAVING 구를 설명할 때 집계함수는 WHERE 구에서는 사용할 수 없다.

 

 

 

3. SELECT 구에서 서브쿼리 사용하기

  • 문법적으로 서브쿼리는 '하나의 항목'으로 취급한다.
  • SELECT 구에서 서브쿼리를 지정할 때는 스칼라 서브쿼리가 필요하다.
  • Oracle 등의 데이터베이스에서는 FROM을 생략할 수 없으므로 FROM DUAL로 지정한다.
    • DUAL은 시스템 쪽에서 데이터베이스에 기본으로 작성되는 테이블.

 

 

4. SET 구에서 서브쿼리 사용하기

  • UPDATE의 SET 구에서도 서브쿼리를 사용할 수 있다.
  • SET구에서 서브쿼리를 사용할 경우에도 스칼라 값을 반환하도록 스칼라 서브쿼리를 지정해야 한다.
  • Ex)
    UPDATE sample54 SET a=(SELECT MAX(a) FROM sample54);​

 

 

 

5. FROM 구에서 서브쿼리 사용하기

  • FROM 구에 서브쿼리를 지정하는 경우 괄호로 SELECT 명령을 묶는다.
  • FROM 구에 기술할 경우 스칼라 값을 반환하지 않아도 된다.
  • SELECT 명령 안에 SELECT 명령이 들어있는 구조를 '네스티드 구조' 또는 '중첩 구조', '내포구조' 라고 부른다.

Ex)

SELECT * FROM (SELECT * FROM sample54) AS sq;

 

실제 업무에서 from 구에 서브쿼리를 지정하여 사용하는 경우

  • FROM 구에서 서브쿼리를 사용하여 LIMIT이 없는 Oracle에서도 행 제한을 할 수 있다.
  • ex)
    SELECT * FROM(
    	SELECT * FROM sample54 ORDER BY a DESC
    )sq
    WHERE ROWNUM <=2;​

 

 

 

6. INSERT 명령과 서브쿼리

  • INSERT 명령에는 VALUES 구의 일부로 서브쿼리를 사용하는 경우, VALUES 구 대신 SELECT 명령을 사용하는 두가지 방법이 있다.
    • VALUES 구의 값으로 서브 쿼리를 사용하는 경우, 스칼라 서브쿼리로 지정해야한다.
    • VALUES 구 대신 SELECT 명령을 사용하는 경우 INSERT SELECT 사용.

 

 

 

 

24강 ) 상관 서브쿼리

  • EXISTS 술어를 사용해 서브쿼리가 반환하는 결괏값이 있는지 조사할 수 있다.
  • EXISTS 를 사용하는 경우 반환된 행이 있는지를 확인해보고 값이 있으면 참, 없으면 거짓을 반환한다.

 

 

1. EXISTS

  • 데이터가 존재하는지 아닌지를 판별
  • Ex) EXISTS를 사용해 '있음' 으로 갱신하기
UPDATE sample551 SET a ='있음' WHERE
	EXISTS (SELECT * FROM sample 552 WHERE no2 = no);
    
SELECT * FROM sample551;

 

sample552 의 열이고 no 는 sample551의 열이다. 

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

 

 

 

2. NOT EXISTS

  • 행이 존재하지 않는 상태가 참이 될 경우 사용

 

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

 

 

 

3. 상관 서브쿼리

  • 부모 명령과 자식인 서브쿼리가 특정 관계를 맺는 것을 '상관 서브쿼리'라고 한다.
  • 양 쪽 테이블명의 열 이름이 같은 경우 테이블명을 붙여 구분한다.

Ex)

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

 

 

 

4. IN

  • 집합 안의 값이 존재하는지를 조사
  • 서브쿼리를 사용할 때 IN을 통해 비교
  • Ex)
    SELECT * FROM sample551 WHERE no IN
    	(SELECT no2 FROM sample552);​

 

IN과 NULL

  • IN에서는 집합 안에 NULL 값이 있어도 무시하지는 않는다.
  • 하지만 NULL=NULL을 비교할 수 없으므로 IN을 사용해도 NULL값을 비교할수는 없다.
  • 따라서 IS NULL을 사용해 비교해야한다.
  • NOT IN의 경우 집합 안에 NULL 있으면 왼쪽 값이 집합 안에 포함되어 있지 않아도 참을 반환한다. 따라서 결과는 UNKNOWN이 된다.