CodeGym /행동 /SQL SELF /FROM에서 서브쿼리 사용하기

FROM에서 서브쿼리 사용하기

SQL SELF
레벨 14 , 레슨 1
사용 가능

이제 토끼굴을 더 깊게 파보자! FROM 구문에서 서브쿼리를 어떻게 쓰는지 알아볼 거야. 이건 SQL 개발자들이 진짜 자주 쓰는 방법인데, 바로 그 자리에서 강력한 임시 테이블을 만들고, 마치 DB에 원래 있던 테이블처럼 재사용할 수 있거든.

예를 들어, 리포트를 만들어야 하는데 계산, 그룹핑, 필터링 같은 작업이 필요해. 근데 서버에 임시 테이블을 따로 만들고 싶진 않아. 그럴 땐? 바로 FROM에서 서브쿼리가 등장하지! 이걸로 할 수 있는 건:

  • 데이터를 임시로 합치거나 집계해서 메인 쿼리 전에 준비할 수 있어.
  • 즉석에서 구조화된 데이터셋을 만들 수 있어.
  • DB에 중간 데이터를 최소한만 저장하게 해서, 작업을 더 간단하게 할 수 있어.

FROM에서의 서브쿼리는 미니 테이블처럼 동작해. 메인 쿼리에서 이걸 테이블처럼 쓸 수 있지. 약간 레고 조립하는 느낌이야: 빠르고, 유연하고, 쓸데없는 오버헤드도 없어 :)

FROM에서 서브쿼리의 기본

FROM에서 서브쿼리를 쓰면 임시 테이블(혹은 서브테이블)을 만들고, 이게 전체 쿼리의 일부가 돼. 이걸 하려면 세 가지 핵심 단계를 따라야 해:

  1. 서브쿼리를 FROM 구문에 괄호로 감싸서 작성해.
  2. 서브쿼리에 alias(별명)을 붙여.
  3. 그 별명을 마치 진짜 테이블처럼 써.

문법

SELECT 컬럼들
FROM (
    SELECT 컬럼들
    FROM 테이블
    WHERE 조건
) AS 별명
WHERE 외부_조건;

좀 무섭게 느껴져? 예시로 바로 가보자.

예시: 학생들과 평균 점수

우리한테 두 개의 테이블이 있다고 해보자:

students (학생 정보 — 이름과 ID):

student_id student_name
1 Alex
2 Anna
3 Dan

grades (학생들의 점수 데이터):

grade_id student_id grade
1 1 80
2 1 85
3 2 90
4 3 70
5 3 75

이제 미션: 학생 목록과 그들의 평균 점수를 구해보자.

먼저 각 학생의 평균 점수를 계산하는 간단한 서브쿼리부터 시작해서, 그걸 메인 쿼리에서 써보자.

SELECT s.student_name, g.avg_grade
FROM (
    SELECT student_id, AVG(grade) AS avg_grade
    FROM grades
    GROUP BY student_id
) AS g
JOIN students AS s ON s.student_id = g.student_id;

결과:

student_name avg_grade
Alex 82.5
Anna 90.0
Dan 72.5

즉석에서 만드는 임시 테이블

FROM에서의 서브쿼리는 데이터 처리를 여러 단계로 해야 할 때 특히 유용해. 예를 들어, 평균 점수뿐만 아니라 각 학생의 최고 점수도 한 번에 계산하고 싶을 때!

SELECT g.student_id, g.avg_grade, g.max_grade
FROM (
    SELECT student_id, 
           AVG(grade) AS avg_grade, 
           MAX(grade) AS max_grade
    FROM grades
    GROUP BY student_id
) AS g;

결과:

student_id avg_grade max_grade
1 82.5 85
2 90 90
3 72.5 75

이렇게 하면 avg_grademax_grade라는 컬럼이 있는 진짜 임시 테이블처럼 쓸 수 있어.

FROM에서 서브쿼리를 언제 쓰면 좋을까?

집계 데이터가 필요할 때. 먼저 평균, 합계, 최대값 같은 계산을 하고, 그 결과를 다른 테이블과 조인하고 싶을 때.

데이터 필터링할 때. 메인 테이블과 합치기 전에 데이터를 미리 걸러내고 싶을 때.

복잡한 쿼리를 단순화할 때. 복잡한 작업을 단계별로 나누면 헷갈리지 않아.

예시: 두 단계로 처리하는 학생 리포트

이번엔 평균 점수가 80점 넘는 학생만 찾고 싶다고 해보자. 먼저 평균 점수를 계산하는 서브쿼리를 만들고, 그걸 필터에 써보자.

SELECT s.student_name, g.avg_grade
FROM students AS s
JOIN (
    SELECT student_id, AVG(grade) AS avg_grade
    FROM grades
    GROUP BY student_id
) AS g ON s.student_id = g.student_id
WHERE g.avg_grade > 80;

결과:

student_name avg_grade
Alex 82.5
Anna 90.0

사용 팁과 주의사항

별명은 꼭 붙이기. 서브쿼리에는 항상 alias(예: AS g)를 붙여야 해. 안 그러면 PostgreSQL이 이 "임시 테이블"을 어떻게 불러야 할지 몰라.

최적화. FROM에서의 서브쿼리는 테이블 조인(JOIN)보다 느릴 수 있어. 특히 서브쿼리 안에서 데이터를 필터링할 때 더 그래.

인덱스. 조인에 쓰는 컬럼, 인덱스, 필터가 잘 최적화되어 있는지 꼭 확인해. 이게 성능에 진짜 큰 영향을 줘.

복잡한 쿼리 예시: 강의와 학생 수

이제 좀 더 어려운 실제 문제를 풀어보자. 이런 테이블이 있다고 해보자:

courses (강의 목록):

course_id course_name
1 SQL Basics
2 Python Basics

그리고 enrollments (학생들의 강의 수강 기록):

student_id course_id
1 1
1 2
2 1

이제 각 강의에 몇 명의 학생이 등록했는지 알고 싶어.

SELECT c.course_name, e.students_count
FROM courses AS c
JOIN (
    SELECT course_id, COUNT(student_id) AS students_count
    FROM enrollments
    GROUP BY course_id
) AS e ON c.course_id = e.course_id;

결과:

course_name students_count
SQL Basics 2
Python Basics 1

강의가 재밌었길 바라! 다음 강의는 더 흥미로울 거야 :)

코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION