[23, 24강] 서브쿼리, 상관 서브쿼리
서브쿼리
: SELECT 명령에 의한 데이터 질의. 하부의 부수적 질의를 의미
- SQL 명령문 안에 지정하는 하부 SELECT 명령으로, 괄호로 묶어 지정
: SELECT 구, FROM 구, WHERE 구 등에서 기술 가능
DELETE의 WHERE에서 서브쿼리 사용하기
DELETE FROM sample1
WHERE a = (
SELECT MIN(a) FROM sample1
);
- 서브쿼리를 이용해 최소값을 구한 뒤, sample1 테이블에서 a 컬럼이 해당 값인 row 삭제
- 서브쿼리 부분을 변수로 저장해서 사용할 수도 있다!
스칼라 값
- 서브쿼리 패턴
- 하나의 값을 반환하는 서브쿼리
- 복수의 행이 반환되지만 열은 하나인 서브쿼리
- 하나의 행이 반환되지만 열이 복수인 서브쿼리
- 복수의 행, 복수의 열이 반환되는 서브쿼리
스칼라 서브쿼리
: 1번 패턴 (SELECT 명령이 하나의 값을 반환)을 '스칼라 값 반환'이라고 표현한다.
- 스칼라 값 반환 SELECT는 서브쿼리로 사용하기 편하다
- = 연산자로 비교할 수 있다
- WHERE 구에서 사용할 수 있으니, 집계함수를 사용해 집계 결과를 조건식에 넣을 수 있다.
하나의 그룹에 다른 값이 여러 개 존재한다면 스칼라 값이 아니다!
SELECT 구에서 서브쿼리 사용하기
스칼라 서브쿼리가 필요하다.
SELECT
(SELECT COUNT(*) FROM sample1) AS sq1,
(SELECT COUNT(*) FROM sample2) AS sq2;
- 상부 SELECT 명령에는 FROM 구가 없다!
: 단, Oracle에서는 FROM 생략 불가능 - FROM DUAL로 지정 필요
SET 구에서 서브쿼리 사용하기
스칼라 서브쿼리가 필요하다.
UPDATE sample1 SET a = (SELECT MAX(a) FROM sample1);
FROM 구에서 서브쿼리 사용하기
스칼라 값이어도, 아니어도 상관 없다.
SELECT * FROM ( SELECT * FROM sample1 ) sq;
-
네스티드(nested) 구조 (=중첩구조 = 내포구조)
: SELECT 명령 안에 SELECT 명령이 들어있는 구조
: 별명을 붙여 서브쿼리의 이름을 지정한다. AS는 생략 가능
: 중첩구조는 몇 단계로든 구성 가능! -
Oracle에서 LIMIT 구의 대체 명령으로 사용 가능
INSERT 명령과 서브쿼리
- VALUES 구의 일부로 서브쿼리 사용
: 서브쿼리는 스칼라 서브쿼리!
INSERT INTO sample1 VALUES (
(SELECT COUNT(*) FROM sample1),
(SELECT COUNT(*) FROM sample2)
);
- SELECT 명령 사용
: VALUES 구 대신 사용한다
: SELECT 결과를 클라이언트로 반환하지 않고 INSERT한다.
: 데이터의 복사나 이동에서 자주 사용한다
INSERT INTO sample1 SELECT 1, 2;
상관 서브쿼리
: 서브쿼리의 일종. EXISTS 술어로 조합하여 서브쿼리를 사용하는 방법
- EXISTS를 사용, 서브쿼리가 반환하는 결괏값이 있는지를 조사한다
: 서브쿼리가 꼭 스칼라값일 필요 X
: 행이 있기만 하면 참을 반환 = 패턴 영향 X
EXISTS
데이터가 존재하는지 아닌지를 판별
UPDATE sample1 SET a='있음' WHERE
EXISTS (SELECT * FROM sample2 WHERE no2=no);
- 서브쿼리를 이용, 행이 존재하는 경우 '있음'으로 갱신
NOT EXISTS
데이터가 존재하지않는지 하는지를 판별
UPDATE sample1 SET a='없음' WHERE
NOT EXISTS (SELECT * FROM sample2 WHERE no2=no);
- 서브쿼리를 이용, 행이 존재하는 않는 경우 '없음'으로 갱신
상관 서브쿼리
부모 명령과 자식인 서브쿼리가 특정 관계를 맺는 것
- 부모 명령과 연관되므로, 서브쿼리 부분을 따로 떼어내어 실행시킬 수 없다
UPDATE sample1 SET a='있음' WHERE
EXISTS (SELECT * FROM sample2 WHERE no2=no);
SELECT * FROM sample2 WHERE no2=no // no2가 불명확. 에러!
- 부모 명령과 서브쿼리의 열명이 동일할 경우, 어느 테이블의 열인지를 명시 필요
UPDATE sample1 SET a='있음' WHERE
EXISTS (SELECT * FROM sample2 WHERE sample2.no2=sample1.no);
IN
집합 안의 값이 존재하는지 조사하는 술어
SELECT * FROM sample1 WHERE no IN (3,5);
// 서브쿼리로 집합 부분 지정 가능
SELECT * FROM sample1 WHERE no IN (
SELECT no2 FROM sample2
);
- or에 비해 깔끔!
- IN은 집합 안의 null을 무시하지 않는다
: IS NULL이 아니라면 null 비교 불가능
: NOT IN에서 null이 있다면, 왼쪽값이 집합에 있더라도 참이 아닌 불명(UNKNOWN)이 된다.
Author And Source
이 문제에 관하여([23, 24강] 서브쿼리, 상관 서브쿼리), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@ej_shin/23-24강-서브쿼리-상관-서브쿼리저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)