서브쿼리 문법
서브쿼리란?
- 서브쿼리는 메인 쿼리(Main Query) 안에 포함된 서브쿼리(또는 내부 쿼리라고도 함)입니다.
- SQL문의 내부에 DBMS가 제공하는 다양한 함수를 넣을 수 있는 것과 마찬가지로 함수가 들어갈 수 있는 위치에는 그 위치에 맞는 결과를 반환하는 또 다른 독립적인 SQL문을 서브쿼리라고 합니다.
- 서브쿼리는 메인쿼리의 칼럼 사용 여부에 따라 연관 서브쿼리와 비연관 서브쿼리로 나뉩니다.
- 연관(Correlated) 서브쿼리: 메인쿼리 칼럼을 서브쿼리에서 사용.
- 비연관(Un-Correlated) 서브쿼리: 메인쿼리의 칼럼을 서브쿼리에서 사용하지 않음.
- 서브쿼리는 메인쿼리의 칼럼 사용 여부에 따라 연관 서브쿼리와 비연관 서브쿼리로 나뉩니다.
- 서브쿼리는 메인 쿼리의 조건으로 사용되거나, 메인 쿼리에 필요한 값을 제공합니다.
- 괄호 ( ) 안에 작성되며, 일반적으로 SELECT문을 포함합니다.
서브쿼리 사용 위치
서브쿼리는 다양한 위치에서 사용될 수 있으며, 용도에 따라 크게 세 가지로 나눌 수 있습니다.
- SELECT 절 안에서 서브쿼리 사용 (스칼라 서브쿼리): 특정 열의 값을 서브쿼리로 생성.
- SELECT문의 칼럼이 입력되는 위치(SELECT, ORDER BY 등)에 들어가는 서브쿼리.
- WHERE (또는 HAVING) 절 안에서 서브쿼리 사용 (중첩 서브쿼리): 조건을 서브쿼리로 설정하여 데이터 필터링.
- 쿼리 안에 다른 쿼리가 중첩되어 들어간 경우를 지칭하며, 중첩 서브쿼리는 다양한 반환값을 가질 수 있습니다.
- FROM 절 안에서 서브쿼리 사용 (인라인 뷰): 서브쿼리 결과를 임시 테이블처럼 사용.
- FROM절의 테이블이 입력되는 위치에 들어가는 서브쿼리.
SELECT 절에서 서브쿼리 사용하기 (스칼라 서브쿼리)
SELECT 절에서 서브쿼리를 사용하면 계산된 값을 조회 결과의 열로 포함시킬 수 있습니다.
예시
SELECT name,
(SELECT AVG(age) FROM students) AS avg_age
FROM students;
- 이 쿼리는 모든 학생의 이름과 함께, 학생 나이의 평균값을 각 행에 avg_age라는 열로 포함시켜 조회합니다.
- 모든 행에 같은 평균 나이 값이 표시됩니다.
WHERE (또는 HAVING) 절에서 서브쿼리 사용하기 (중첩 서브쿼리)
WHERE 절에서 서브쿼리를 사용하면 서브쿼리의 결과를 조건으로 설정하여 특정 데이터를 필터링할 수 있습니다.
예시 1: 특정 조건을 만족하는 행 조회하기
SELECT name
FROM students
WHERE age > (SELECT AVG(age) FROM students);
- 이 쿼리는 학생 나이의 평균보다 나이가 많은 학생의 이름을 조회합니다.
- WHERE 절의 조건으로 서브쿼리의 결과(평균 나이)를 사용했습니다.
예시 2: IN과 함께 사용하기
서브쿼리의 결과가 여러 값일 때는 IN을 사용하여 필터링할 수 있습니다.
SELECT name
FROM students
WHERE id IN (SELECT id FROM honors WHERE grade = 'A');
- honors 테이블에서 grade가 'A'인 학생들의 ID를 가져와 students 테이블에서 해당 ID에 해당하는 학생의 이름을 조회합니다.
FROM 절에서 서브쿼리 사용하기 (인라인 뷰)
FROM 절에서 서브쿼리를 사용하면 서브쿼리를 임시 테이블(derived table)처럼 사용할 수 있습니다.
주로 복잡한 데이터 조작이 필요한 경우 유용합니다.
뷰(view)가 기존의 테이블로부터 파생되어 동적으로 생성되는 테이블인 것과 마찬가지로 인라인 뷰 쿼리 실행 시 생성되는 동적 테이블이라고 할 수 있습니다.
예시
SELECT name, avg_grade
FROM (SELECT student_id, AVG(grade) AS avg_grade
FROM grades
GROUP BY student_id) AS avg_grades
JOIN students ON students.id = avg_grades.student_id;
- 이 쿼리에서는 grades 테이블에서 학생별 평균 성적을 계산한 결과를 avg_grades라는 임시 테이블로 생성한 후, students 테이블과 조인하여 학생 이름과 평균 성적을 함께 조회합니다.
서브쿼리의 종류
- 단일 행 서브쿼리 (Single-row Subquery): 하나의 값만 반환하는 서브쿼리로, =와 같은 단일 비교 연산자를 사용합니다.
SELECT name
FROM students
WHERE age = (SELECT MAX(age) FROM students);
이 쿼리는 나이가 가장 많은 학생의 이름을 조회합니다.
- 다중 행 서브쿼리 (Multi-row Subquery): 여러 값을 반환하는 서브쿼리로, IN, ANY, ALL 같은 연산자와 함께 사용됩니다.
SELECT name
FROM students
WHERE age IN (SELECT age FROM students WHERE grade = 'A');
이 쿼리는 grade가 'A'인 학생들의 나이와 같은 나이를 가진 학생들의 이름을 조회합니다.
- 상관 서브쿼리 (Correlated Subquery): 서브쿼리가 메인 쿼리의 각 행에 의존하는 경우입니다. 일반적으로 WHERE 절에서 사용됩니다.
SELECT name
FROM students s1
WHERE age > (SELECT AVG(age) FROM students s2 WHERE s1.class = s2.class);
이 쿼리는 각 학생의 반(class)에서 나이가 평균보다 많은 학생의 이름을 조회합니다.
서브쿼리는 SQL에서 복잡한 데이터 조회 및 조건 필터링을 가능하게 하며, 여러 테이블에서 데이터를 동적으로 가져올 때 매우 유용하게 활용할 수 있습니다.
서브쿼리는 SQL을 통해 복잡한 조건 설정과 데이터 조작을 효율적으로 수행할 수 있는 중요한 도구입니다. 데이터를 동적으로 가져오고 다양한 조건에 따라 세밀하게 필터링하는데 유용한 서브쿼리를 잘 활용한다면, 데이터 분석 및 보고서 작성의 정확성과 효율성을 크게 향상시킬 수 있습니다. 이 글을 통해 서브쿼리의 기본 원리와 사용 방법을 이해하는 데 도움이 되었기를 바랍니다.
'프로그래밍 언어 > SQL' 카테고리의 다른 글
[SQL 개념 정리 11] 그룹함수 (0) | 2024.11.15 |
---|---|
[SQL 개념 정리 10] 집합연산자 (0) | 2024.11.15 |
[SQL 개념 정리 8] CTE (WITH 문) (0) | 2024.11.14 |
[SQL 개념 정리 7] IF/IFNULL 함수와 CASE 함수 (1) | 2024.11.13 |
[SQL 개념 정리 6] WINDOW 함수 (0) | 2024.11.13 |
데이터 분석을 공부하고 카페를 열심히 돌아다니는 이야기
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!