SQL 첫걸음(ch23. 서브쿼리 ~ ch24. 상관 서브쿼리)

김도형·2022년 10월 11일
0

23장 서브쿼리

서브쿼리는 SELECT 명령에 의한 데이터 질의, 상부가 아닌 하부의 부수적인 질의를 의미

사용 구

  • DELETE
  • SET
  • FROM
  • INSERT
  • 문법
(SELECT 명령)

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

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

  • DELETE + SELECT 결합 시킬 수 있음.

단, MySQL에서는 DELETE + SELECT 결합 명령이 안되기 때문에 SELECT + SELECT 로 변경해야함. 아니면 set 변수를 사용하며 된다.

MySQL

  • set
set @a = (SELECT MIN(a) FROM sample54);
DELETE FROM sample54 WHERE a = @a;
  • SELECT + SELECT : 인라인 뷰로 임시 테이블을 만들도록 처리
DELECT FROM sample54 WEERE a = (SELECT a FROM (SELECT MIN(a) AS a FROM sample54) AS x);

스칼라 값

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

SELECT MIN(a) FROM sample54;
  • 하나의 값만 반환
MIN(a)
80

= 연산자를 사용하여 비교할 경우에는 스칼라 값끼리 비교할 필요가 있다.
이것을 스칼라 서브쿼리라고 함.

그래서 '스칼라 서브쿼리'이며, WHERE 구 사용할 수 있으므로 집계한 결과를 조건식 사용 가능

MySQL와 Oracle SELECT 구 서브쿼리 사용

  • MySQL 은 FROM 생략 가능
SELECT
	(SELECT COUNT(*) FROM sample51) AS sq1,
    (SELECT COUNT(*) FROM sample54) AS sq2;
  • Oracle 은 FROM 생략 불가로 FROM DUAL로 지정 해줘야한다.
SELECT
	(SELECT COUNT(*) FROM sample51) AS sq1,
    (SELECT COUNT(*) FROM sample54) AS sq2 FROM DUAL;

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

UPDATE sample54 SET a = (SELECT MAX(a) FROM sample54);

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

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

단, Oracle은 AS 붙이지 않는다.

실제 업무에서 FROM 구에 서브쿼리 지정사용 경우(Oracle)

Oracle에는 LIMIT 구를 사용할 수 없어 ROWNUM 행 개수 제한할 수 있지만, 정렬 후 상위 몇 건을 추출하는 조건을 붙일 수 없다.
[이유는 ROWNUM의 경우 WHERE 구로 인해 번호가 할당되기 때문]
FROM 구에서는 서브쿼리를 사용하여 정렬 후 상위 몇 건 추출 가능

SELECT * FROM (
	SELECT * FROM sample54 ORDER BY a DESC
)sq
WHERE ROWNUM <= 2;

INSERT 명령과 서브쿼리

방법은 2가지가 있다.

  • VALUES 구에서 서브쿼리 사용하기
  • SELECT 결과를 INSERT하기(INSERT SELECT)

VALUES 구 예제

INSERT INTO sample541 VALUES(
	(SELECT COUNT(*) FROM sample51),
    (SELECT COUNT(*) FROM sample54)
);
ab
53

SELECT(INSERT SELECT) 예제

INSERT INTO sample541 SELECT 1, 2;
ab
53
12

INSERT SELECT

SELECT 명령이 반환하는 값이 꼭 스칼라 값일 필요가 없다.
SELECT 테이블 반환 열 수 = INSERT 테이블 열 수 일치해야함.
또한 테이블의 행 복사하기 가능

INSERT INTO sample542 SELECT * FROM sample543;

24장 상관 서브쿼리

  • SYNTAX
EXISTS (SELECT 명령)

EXISTS는 반드시 스칼라 값을 반환할 필요 없음.
단지 반환된 행이 있는지 없는지 참(true)과 거짓(false) 반환

추가로 열에 테이블명 붙이는 것이 에러 발생을 방지할 수 있다.
ex : sample551.no

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

변경 전
[sample551 테이블]

noa
1NULL
2NULL
3NULL
4NULL
5NULL

[sample552 테이블]

no 2
3
5

변경 후

ab
1NULL
2NULL
3있음
4NULL
5있음

NOT EXISTS

간단히 반대로 반환된다.

IN

집합 비교 때는 IN 사용
스칼라 비교 때는 = 연산자 사용
그래서 서브쿼리를 사용할 때 IN 많이 사용

IN과 NULL

  • 보통 집계함수의 NULL 무시됐지만, IN에서의 집합 안의 NULL을 무시하지 않는다.
  • 단, NULL = NULL을 제대로 계산할 수 없어, IN 사용해도 NULL 비교 못함.
  • 즉, NULL 비교할 때 IS NULL 사용
  • NOT IN인 경우, 참 일지라도 불명(UNKNOWN) 반환

출처 : SQL 첫걸음 아사이 아츠시 지음 [한빛미디어]

profile
3년간 웹/앱, 자동제어 QA 🔜 개발자로 전향하여 현재 교육 회사에서 백엔드 개발자로 근무 중입니다.(LinkedIn : https://www.linkedin.com/in/dohyoung-kim-5ab09214b)

0개의 댓글