DB/MySQL

서브쿼리(Subquery)

annovation 2025. 1. 6. 08:42

서브쿼리(Subquery) 

서브쿼리(Subquery)는 SQL에서 다른 쿼리의 내부에 포함되어 실행되는 쿼리를 의미합니다.

  • 서브쿼리는 주로 메인 쿼리(Main Query)의 일부로 동작하며, 메인 쿼리에서 필요한 데이터를 계산하거나 필터링하는 데 사용됩니다.
  • 서브쿼리는 항상 괄호 ()로 감싸서 사용됩니다.

반환 값에 따른 분류 (연산자)

 

1. 단일 행 서브쿼리 (Single-row Subquery)

  • 서브쿼리의 실행 결과로 1건 이하의 행 반환
  • 단일행 비교 연산자 =, <, <=, >=, <> 와 함께 사용
  • ex. 특정 학생의 최고 점수를 가져올 때
SELECT name
FROM students
WHERE score = (SELECT MAX(score) FROM students);

 

2. 다중 행 서브쿼리(Multi-row Subquery)

  • 서브쿼리의 실행 결과로 여러 건의 행 반환
  • 다중행 비교 연산자 IN, ALL, ANY, SOME, EXIST 와 함께 사용
  • ex. 특정 과목의 평균 점수 이상인 학생들의 이름을 가져올 때
SELECT name
FROM students
WHERE score IN (SELECT DISTINCT score FROM exams WHERE score >= 70);

 

3. 단일 열 서브쿼리(Single-column Subquery)

  • 실행 결과로 단일 열(Column)을 반환합니다.
  • 주로 특정 조건의 데이터를 메인 쿼리에서 비교하거나 필터링할 때 사용됩니다.
  • ex. 학생의 이름을 특정 과목에서 받은 점수로 필터링할 때
SELECT name
FROM students
WHERE id IN (SELECT student_id FROM exams WHERE subject = 'Math' AND score > 80);

 

4. 다중 열 서브쿼리(Multi-column Subquery)

  • 실행 결과로 여러 열을 반환합니다.
  • 여러 열 데이터를 비교하거나 조합해야 할 때 유용합니다.
  • ex. 학생들의 이름과 점수를 특정 기준으로 가져올 때
SELECT name, score
FROM students
WHERE (name, score) IN (SELECT name, score FROM exams WHERE score > 85);

실행 방식에 따른 분류 

 

1. 독립 서브쿼리 (Independent Subquery)

  • 메인 쿼리와 관계없이 독립적으로 실행될 수 있습니다.
  • ex. 가장 최근 시험 날짜를 가져올 때
SELECT name
FROM students
WHERE exam_date = (SELECT MAX(exam_date) FROM exams);

 

2. 상관 서브쿼리(Correlated Subquery)

  • 서브쿼리가 메인 쿼리의 각 행에 의존하여 실행됩니다.
  • 반복 실행되므로 성능이 떨어질 수 있지만, 복잡한 조건을 구현하는 데 유용합니다.
  • ex. 학생별 최고 점수를 가져올 때
SELECT name, score
FROM students AS s1
WHERE score = (SELECT MAX(score) FROM students AS s2 WHERE s1.id = s2.id);

사용 위치에 따른 분류

 

1. SELECT 절에서 사용

  • 데이터 변환이나 가공이 필요한 경우 사용됩니다.
  • ex. 학생별 총점을 가져올 때
SELECT name, (SELECT SUM(score) FROM exams WHERE exams.student_id = students.id) AS total_score
FROM students;

 

2. WHERE 절에서 사용

  • 조건 필터링에 활용됩니다.
  • ex. 특정 과목에서 최고 점수를 받은 학생의 이름을 가져올 때
SELECT name
FROM students
WHERE id = (SELECT student_id FROM exams WHERE score = (SELECT MAX(score) FROM exams));

 

3. FROM 절에서 사용

  • 임시 테이블처럼 서브쿼리를 사용하여 데이터 소스를 만듭니다.
  • ex. 학생별 평균 점수를 임시 테이블로 만들어 처리
SELECT name, avg_score
FROM (SELECT student_id, AVG(score) AS avg_score FROM exams GROUP BY student_id) AS temp_table
JOIN students ON students.id = temp_table.student_id;

 

4. HAVING 절에서 사용

  • 집계 함수 조건을 필터링할 때 사용됩니다.
  • ex. 평균 점수가 특정 값 이상인 그룹을 가져올 때
SELECT class_id, AVG(score) AS avg_score
FROM exams
GROUP BY class_id
HAVING AVG(score) > (SELECT AVG(score) FROM exams);

주의사항

  1. 성능 문제
    • 상관 서브쿼리(Correlated Subquery)는 메인 쿼리의 각 행에 대해 반복 실행되므로 성능이 저하될 수 있습니다.
    • 가능한 경우 JOIN으로 대체하여 성능을 개선하세요.
  2. 서브쿼리의 독립성
    • 서브쿼리는 메인 쿼리와 독립적으로 실행 가능한 형태인지 확인하여 디버깅이 용이하도록 작성
  3. 단일 값 반환 보장
    • 스칼라 서브쿼리에서는 반드시 단일 값을 반환해야 합니다. 그렇지 않으면 오류가 발생합니다.

출처

OpenAI ChatGPT (https://openai.com)

 

'DB > MySQL' 카테고리의 다른 글

DELETE vs TRUNCATE  (0) 2025.02.26
트랜젝션 (Transaction)  (1) 2025.02.01
GROUP_CONCAT feat. DISTINCT  (0) 2025.01.03
GROUP BY  (0) 2025.01.02
JOIN  (2) 2025.01.01