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/
Author
Datamind
Published at
2021-08-21
License
CC BY-NC-SA 4.0