MYSQL 서브쿼리 SUB QUERY

byeolhee·2022년 10월 17일
0

서브쿼리란?

쿼리문 안에 또 다른 쿼리문이 포함된 구문이다.
언제나 단순히 select 문을 구사할때 where 조건에 ㅇㅇ테이블의 번호는 = 1번이다. 이런식으로 단순한 문을 구사하면 참 좋겠지만 사는게 단순하지가 않다. 복잡한 질의로 테이블에서 답을 추출해내는게 필요한데 그때 필요한게 서브쿼리를 사용하곤 한다.

SELECT * FROM tb_class_masters WHERE classNum in (
	select classNum from tb_class_masters where stuMathAvg > '80'
);
## 1. 80보다 학생 수학평균이 큰 반의 번호 목록 을 구함 (내부쿼리)
## 2. 메인쿼리(부모, 외부쿼리) 실행

부모와 서브쿼리와 테이블이 달라도 상관없다. where 의 조건을 가져오는 것이기 때문에. 서브쿼리리는 ()로 감싸 사용한다.
물론 where 조건에만 사용하는건 아니다. select (서브쿼리) from 로 가져올 수도 있고 from 뒤에 붙어서 하나의 테이블처럼 사용할 수도 있다. 위에 예시를 든 것처럼 where 조건처럼 사용해도 되고. 명칭은 이렇게 부른다.

서브쿼리 종류

SELECT (SUB) FROM  : 스칼라  서브쿼리, 다른 테이블에서 값 가져올때 사용, 하나의 레코드만 리턴가능.
SELECT * FROM (SUB) : 인라인 뷰, 테이블처럼 씀. 이 경우 AS 로 별칭 지정해야 한다.
SELECT * FROM WHERE AA = (SUB) : 일반 서브쿼리.

WHERE 문에 나타나는 서브뭐리는 조건값을 SELECT 로 특정하면 결과값이 하나여야 오류가 나지 않는다. 늘 문법이 맞는것같은데 안되면 대부분 이 에러라 슬프다.

서브쿼리는 SELECT 문으로만 작성 가능하고 ORDER BY 사용이 쉽지 않다. ORDER BY는 최상위 절로 옮겨서 사용하던가 LIMIT를 사용해 갯수를 제한하면 된다.

서브쿼리 사용처

서브쿼리 사용가능한곳을 정리해보자면
SELECT, FROM, WHERE, HAVING, ORDER BY, INSERT의 VALUE, UPDATE의 SET, DELETE WHERE

단, UPDATE, DELETE는 자기 테이블의 데이트를 바로 사용하지 못해서 에러를 맞기 쉽다. 그래서 서브쿼리를 한 개 더 두어서 다중으로 두어야 한다.

DELETE FROM tb_class_masters
WHERE idx not in (SELECT new.mind
   FROM (SELECT min(idx) as mind 
       	 	FROM tb_class_masters
        	GROUP BY classCode) new);
            
// 1. classCode로 묶은 최소 idx 값을구하고 new라는 as 로 묶자! (classCode 중복이 여러개일 경우 상정),
// 2. 그 최소 idx 에 포함되지 않는걸 삭제, 즉 최소 idx 1개 냅두고 classCode 뭉텅이를 없앰

처음에 서브쿼리 접했을때는 좀 멘붕이고, 아직도 사용할때 단일값 맨날 아니라고 경고, 에러 뜨는데 그래도 유용한건 사실이다. 간단한 문장부터 복잡하게 단계별로 하다보면 조금은 이해하기 쉬웠다.

간단한 문장부터 시작하는 서브쿼리

  1. 그놈이 그놈이다.
SELECT classCategory FROM tb_class_masters WHERE classNum = '12';
// 12번 반의 카테고리를 출력
SELECT classLeader FROM tb_classList WHERE classCategory = '컴퓨터공학';
// 컴퓨터공학과의 반장을 출력

//서로 다른 출력문을 쉐킷 해보자.
// * WHERE 서브쿼리에 단일값이 나와야 된다는 것을 잊지말자.
▼▼▼
SELECT classLeader FROM tb_classList where classCategory = (SELECT classCatgory FROM tb_class_masters WHERE classNum = '12')
  1. 레벨업
SELECT classNum FROM tb_class_masters WHERE stuMathAvg = '90';
▼▼▼
SELECT classNum FROM tb_class_masters WHERE stuMathAvg = (SELECT stuMathAvg FROM tb_classList WHERE stuMathAvg = '90');
▼▼▼
SELECT grade FROM 
SELECT classNum FROM tb_class_masters WHERE stuMathAvg = (SELECT stuMathAvg FROM tb_classList WHERE stuAvg = '90');

in 을 하용하면 단일값 처리같은게 되기 때문에 오른쪽 항이 다수의 값을 가져와도 처리 가능한것 같다.

profile
데이터 우주를 헤맵니다. 응답하라 데이터

0개의 댓글