[Learning SQL] 서브쿼리

반응형
반응형

서브쿼리?는 무엇을 말하는 것일까요?
곰곰히 생각해봅시다.
이름에서 알 수 있듯이 서브 쿼리는 주 쿼리를 도와 주는 쿼리라고 할 수 있습니다.

그러면 주 쿼리는 무엇일까요?

select * from block;

사실 서브 쿼리나 주 쿼리나 별 다를게 없습니다.
지금까지 배운것을 전부 넣어보겠습니다.

select * from block
where color = 'black'
group by second_color
having size < 20;

그러면 서브쿼리는 어디에 추가 할 수 있을까요?
네 맞습니다,

서브 쿼리는 어디든 넣을 수 있습니다.(적어도 select에서는 말이죠)

위 코드의 열을 확인해보면 *라는 와일드 카드가 보인다는 것을 알 수 있습니다.

여기에서 와일드 카드의 역할은 모든 열을 출력 시킨다는 이야기입니다.
그러면 생각해봅시다.

다음과 같은 쿼리가 있다고 생각해봅시다.

select (select color from block2) as color from block;

이것은 맞는 쿼리일까요?

이것은 맞는 쿼리입니다. 왜냐하면 두 번째 select를 통해 block2의 color를 가져올 수 있습니다.
이것을 원 쿼리(block)에서 어떻게 사용이 될지는 모르겠지만,
가능하다고 가정한다면, color라는 키워드는 block2의 color를 사용이 된다는 것을 알 수 있습니다.
이렇게 단일 열을 출력라는 쿼리를 [스칼라 서브쿼리]라고 부른다고 합니다.
또한, select 서브쿼리는 스칼라 서브쿼리로 작성해야 됩니다.

스칼라가 단일이라는 뜻을 가지고 있나 봅니다. 


하나의 수치(數値)만으로 완전히 표시되는 양. 방향의 구별이 없는 물리적 수량임. 질량·에너지·밀도(密度)·전기량(電氣量) 따위.
구글 사전

두 번째, from뒤에 존재하는 서브쿼리
여기서 from의 역할을 생각해봅시다.
from은 어떤 테이블인지 정의하기 위해 작성이 되어집니다. 

그러면
다음과 같은 쿼리가 있다고 생각해봅시다.

select * from (select * from block);

정말 의미없는 쿼리이긴 하지만 이것 또한 틀린 쿼리는 아닙니다.
왜냐하면 from뒤에는 테이블이 나와야 합니다.
그것을 서브쿼리를 통해 만들어줬습니다.

애초에 select를 사용한다는 건 테이블로 만든다는 행위이기 때문입니다.
그렇다는건 결국 select * from block 이 block이 되는것이기때문에
select * from block과 같은 결과를 리턴하게 되는거죠.

그러면 이러한 쿼리 처럼 여기에 작성하는 것은 의미가 없을 까요?
그렇지는 않습니다.
만약에 새로운 테이블이 필요한데 다른 테이블을 참조해서 검색을 해야하는 경우 유용합니다.
즉, 조인을 사용해야 이 서브쿼리가 비로소 빛을 바란다는 것을 알 수 있습니다.

하지만 아쉽게도 조인을 학습하지 않았기 때문에 지금 당장 이 부분은 100% 활용하기는 어려울것 같네요.

여담으로 jpa에서는 이 서브쿼리는 지원하지 않는다고 합니다.

마지막으로 where절
여기를 가장 많이 사용이 될 것 같습니다.

왜 group by, having은 하지 않는 이유는 어차피 이들은 응용이 문제이지 새로운게 아니라고 생각했기 때문입니다.

select * from block
where color = (select red from redSeq);

where은 지금까지 학습한 select, from과는 조금 느낌이 다릅니다.
이 둘같은 확실한 방향성은 존재하지만(select => 스칼라 서브쿼리 , from => 인 라인 서브쿼리[테이블 만드는거])

 where절은 조건문이 하나를 허용하는지 여러개를 허용하는지 확인 해합니다.
예를 들어 위 쿼리 같은 경우

select red from redSeq

안에는 red라는 글자만 존재한다고 가정해봅시다.

그러면 color는 red와 매핑이 되어집니다.
하지만 red안에는 red만 존재 하는것이 아니라 pink, glay, black등등이 포함이 된다고 생각해봅시다.

애초에 = 라는건 1:1매핑이기 때문에 이러한 경우라면 에러가 터집니다.(틀렸다는 뜻이죠)

하지만 다음과 같다면 어떨 까요?

select * from block
where color in (select red from redSeq);

in 키워드는 select의 모든 값들을 가져옵니다. 
이는 다음과 같습니다. color = 'pink' or color = 'red' ....
여기서 알 수 있는 것은 in 은 1:다 매핑이라는 것을 알 수 있습니다.
즉, where 서브쿼리는 조건이 단일 매핑인지 다중 매핑인지 중요합니다.

서브쿼리는 실제 존재하는 테이블은 아닙니다. 서브쿼리는 이미 존재하는 쿼리를 가공해서 만든거라 생각하면 될 것 같습니다.

insert into (v1,v2) 테이블 (select * from block);
이것도 서브쿼리입니다. 다만 여기에서는 입력할 열(select의 열) 갯수와 파라미터의 갯수(v1,v2)가 일치해야 됩니다.

서브쿼리는 sql을 어렵게 만드는 주범중 하나입니다.
그러니 이들을 이기기 위해 노력합시다.

반응형

'sql' 카테고리의 다른 글

[Learning SQL] 트랜잭션  (0) 2021.05.22
[Learning SQL] 내부 조인 vs 외부 조인  (0) 2021.05.12
[Learning SQL] 그룹화와 집계  (0) 2021.04.28
[LearningSql] 집합 연산자  (0) 2021.04.20
[LearningSql] 다중 테이블 쿼리  (0) 2021.04.13

댓글

Designed by JB FACTORY