Categories
Tags
AI airflow alias book build clang closure collection commandline config container DB decorator docker draft format functional generic git gradle intellij java JPA k3s k8s kafka kotlin linux loki monitoring msa neovim network nix poetry pointer python reflection shortcut Spring sql system-design testing web zero-copy
1045 words
5 minutes
[SQL]간단한 서브쿼리 용법
간단한 서브쿼리 용법 정리
Subquery
Concept
- 서브쿼리 : Subquery. 서브쿼리는 하나의 SQL쿼리 안에 포함된 다른 SQL쿼리를 말한다. : SQL
서브쿼리 사용상황
- 가장 기본적으로는 알려지지 않은 조건을 사용해서 조회해야할 때 사용
- DB에 접근하는 속도를 향상시킬 때
사용시 주의점
- 항상 괄호로 감싸서 사용할 것
- 서브쿼리의 결과가 2건 이상이라면(다중행) 반드시 비교연산자와 함께 사용한다,
- 서브쿼리 내에서는 order by 사용 못함( order by는 쿼리에서 하나만 사용)
- 서브쿼리는 메인쿼리의 컬럼을 모두 사용할 수 있지만, 메인쿼리는 서브쿼리의 컬럼을 사용할 수 없다.
- 질의 결과에 서브쿼리 컬럼을 표시해야 한다면 조인 방식으로 변환하거나 함수, 스칼라 서브쿼리 등을 사용해야 한다.
종류
단일 행 서브쿼리 : 특정 행을 반환. 이 행을 조건절도도 사용가능
- ex) 평균값알아내는 서브쿼리를 통해 평균값 이상의 그룹을 출력
다중행 서브쿼리 : 결과가 2건이상 반환되는 서브쿼리. 반드시 비교연산자와 함께 사용. Where 절에 괄호로 들어간다.
- IN(서브쿼리) : 서브쿼리의 결과에 존재하는 값과 동일한 조건의미
- ALL(서브쿼리) : 모든 값을 만족하는 조건
- ANY(서브쿼리) : 비교연산자에 ”>” 를 썼다면 ANY가 어떤 하나라도 맞는지 조건이기 때문에 결과중에 가장 작은값보다 크면 만족한다.
- EXIST(서브쿼리) : 서브쿼리의 결과를 만족하는 값이 존재하는지 여부 확인. 존재유무만 확인하기에 1건만 찾으면 더 이상검색안함
다중 컬럼 서브쿼리 : 서브쿼리 결과로 여러 개의 컬럼이 반환되어 메인쿼리 조건과 동시에 비교되는 것.
-- 다중컬럼 서브쿼리 select ord_num, agent_code, ord_date, ord_amount from orders where(agent_code, ord_amount) IN (SELECT agent_code, MIN(ord_amount) FROM orders GROUP BY agent_code);
Where 절의 Subquery
- 비교연산자 IN 사용
# 특정 행 반환 SELECT employee_id, first_name, last_name FROM employees WHERE department_id IN (SELECT department_id FROM departments WHERE location_id = "찾는 아이디") ORDER BY first_name , last_name;
- MAX나 MIN 사용
# where 절에서 서브쿼리로 정의한 조건을 select 절에 쓸 수 있다. SELECT employee_id, first_name, last_name, salary FROM employees WHERE salary = (SELECT MAX(salary) FROM employees) ORDER BY first_name , last_name;
- AVG로 조건걸기
SELECT employee_id, first_name, last_name, salary FROM employees WHERE salary > (SELECT AVG(salary) FROM employees);
- 서브쿼리 조건문처럼 사용하기
SELECT * FROM tutorial.sf_crime_incidents_2014_01 WHERE Date = (SELECT MIN(date) FROM tutorial.sf_crime_incidents_2014_01 )
FROM 절의 Subquery(Inline View)
- SQL이 실행될 때만 동적으로 생성되는 Inline view
SELECT MAX(items), MIN(items), FLOOR(AVG(items)) FROM (SELECT orderNumber, COUNT(orderNumber) AS items FROM orderdetails GROUP BY orderNumber) AS lineitems;
- 파생테이블은 반드시 alias를 가진다,
select substring(address,1,2) as region, count(*) as review_count from review as r left outer join member as m on r.mem_id = m.id group by substring(address,1,2) having region is not null and region != '안드' select avg(review_count), max(review_count), min(review_count) from (select substring(address,1,2) as region, count(*) as review_count from review as r left outer join member as m on r.mem_id = m.id group by substring(address,1,2) having region is not null and region != '안드') as review_count_summary #서브쿼리로 탄생한 파생테이블은 반드시 alias를 가져야 한다
— Join과 서브쿼리 같이 사용하기
SELECT * FROM tutorial.sf_crime_incidents_2014_01 incidents JOIN ( SELECT date FROM tutorial.sf_crime_incidents_2014_01 ORDER BY date LIMIT 5 ) sub ON incidents.date = sub.date
SELECT 절의 Subquery(Scala Subquery)
- SELECT 절 안에 SELECT가 있을 경우 Scala 서브쿼리라 부르며 기본적으로 한 행만 리턴한다.
SELECT PLAYER, HEIGHT , (SELECT AVG(HEIGHT) FROM PLAYER X WHERE X.TEAM_ID = P.TEAM_ID) FROM PLAYER_P
- 기본적으로 outer join이 적용되어 있다.
- 쿼리 수행 횟수를 최소화하기 위해서 입력값과 출력값을 내부 캐시에 저장한다.
- 대용량 데이터를 처리할 경우 속도가 느려질 수 있다.
SELECT A.PKID , A.TITLE , NVL(B.NAME, '탈퇴한 회원'), B.NAME , (SELECT COUNT(*) FROM REPLY WHERE P_PKID = B.PKID) AS COUNT1 FROM BOARD B LEFT OUTER JOIN MEMBER M ON B.MEM_NO = M.PKID
References & annotation
[SQL]간단한 서브쿼리 용법
https://yjinheon.netlify.app/posts/02de/de-sql-subquery/