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이 된다.