SQL 포맷터: SQL 쿼리 정리하기

· 12분 읽기

목차

SQL 포맷팅이 중요한 이유 이해하기

SQL을 다뤄본 사람이라면 쿼리가 금방 엉망이 될 수 있다는 것을 알 것입니다. 수백 줄이 빽빽하게 모여 있는 정리되지 않은 스크립트를 이해하려고 몇 시간을 보내는 상황을 상상해보세요. 재미없죠?

적절한 SQL 포맷팅은 코드를 깔끔하고 사람이 읽기 쉽게 유지하는 데 필수적입니다. SQL 포맷터는 깔끔한 책상 서랍 정리함처럼 작동하여 개발자가 쿼리를 깨끗하고 효율적으로 작업할 수 있도록 도와줍니다.

줄 바꿈도 없고 들여쓰기도 없는 거대한 쿼리를 디버깅하려고 한다고 생각해보세요. 고통스럽습니다. 구두점이나 단락 구분 없이 책을 읽으려는 것과 비슷합니다. 눈이 흐려지고 한 생각이 끝나고 다른 생각이 시작되는 지점을 놓치게 됩니다.

적절한 포맷팅은 여러 개발자가 같은 프로젝트에서 작업할 때 오류를 줄이는 데도 도움이 됩니다. 모두가 따를 수 있는 통일된 구조를 제공하여 코드 리뷰를 더 빠르고 효과적으로 만듭니다. 팀의 모든 사람이 같은 방식으로 SQL을 포맷하면 새로운 개발자의 온보딩이 더 원활해지고 지식 전달이 더 자연스럽게 이루어집니다.

가독성 외에도 포맷된 SQL 쿼리는 버전 관리 시스템에서 더 나은 성능을 발휘합니다. 커밋 간에 정확히 무엇이 변경되었는지(새로운 JOIN 절, 수정된 WHERE 조건) 볼 수 있으면 데이터베이스 로직의 진화를 정확하게 추적할 수 있습니다.

SQL 포맷터를 사용해야 하는 이유

SQL 포맷터는 단순히 있으면 좋은 도구가 아닙니다. 코드를 관리하는 데 도움을 주는 추가 인력과 같습니다. 생산성을 높이는 방법을 자세히 살펴보겠습니다:

🛠️ 직접 사용해보세요: SQL 포맷터 & 뷰티파이어 | JSON 포맷터 & 검증기

핵심 SQL 포맷팅 원칙과 모범 사례

특정 도구를 살펴보기 전에 SQL 포맷팅을 효과적으로 만드는 기본 원칙을 확립하겠습니다. 이러한 가이드라인은 읽기 쉽고 유지 관리 가능한 데이터베이스 코드의 기초를 형성합니다.

키워드 대문자화

대부분의 SQL 스타일 가이드는 SELECT, FROM, WHERE, JOIN, ORDER BY와 같은 SQL 키워드를 대문자로 표기할 것을 권장합니다. 이는 SQL 구문과 실제 데이터 요소(테이블 이름, 열 이름, 별칭) 간의 시각적 구분을 만듭니다.

-- 좋음
SELECT customer_id, order_date, total_amount
FROM orders
WHERE order_date >= '2026-01-01';

-- 덜 읽기 쉬움
select customer_id, order_date, total_amount from orders where order_date >= '2026-01-01';

들여쓰기와 줄 바꿈

각 주요 절은 새 줄에서 시작해야 하며, 중첩된 요소에 대해 일관된 들여쓰기를 사용해야 합니다. 이는 쿼리의 논리적 구조를 반영하는 시각적 계층 구조를 만듭니다.

SELECT 
    c.customer_name,
    c.email,
    COUNT(o.order_id) AS total_orders,
    SUM(o.total_amount) AS lifetime_value
FROM customers c
LEFT JOIN orders o 
    ON c.customer_id = o.customer_id
WHERE c.registration_date >= '2025-01-01'
GROUP BY c.customer_id, c.customer_name, c.email
HAVING COUNT(o.order_id) > 5
ORDER BY lifetime_value DESC;

열 정렬

SELECT 문과 조인 조건에서 열을 정렬하면 스캔 가능성이 향상됩니다. 눈이 길을 잃지 않고 열 목록을 빠르게 아래로 이동할 수 있습니다.

쉼표 배치

두 가지 사고 방식이 있습니다: 후행 쉼표(각 줄 끝) 및 선행 쉼표(각 줄 시작). 선행 쉼표는 디버깅 중에 줄을 주석 처리하기 쉽게 만들지만, 후행 쉼표가 더 일반적이고 대부분의 개발자에게 더 자연스럽게 느껴집니다.

프로 팁: 하나의 쉼표 스타일을 선택하고 전체 프로젝트에서 일관되게 사용하세요. 어떤 스타일을 선택하느냐보다 일관성이 더 중요합니다.

포맷팅으로 SQL 쿼리 이해하기

포맷팅이 만드는 극적인 차이를 보여주는 실제 예제를 살펴보겠습니다. 레거시 시스템에 나타날 수 있는 포맷되지 않은 쿼리는 다음과 같습니다:

select p.product_id,p.product_name,p.category,c.category_name,sum(oi.quantity) as total_sold,sum(oi.quantity*oi.unit_price) as revenue from products p join categories c on p.category_id=c.category_id join order_items oi on p.product_id=oi.product_id join orders o on oi.order_id=o.order_id where o.order_date between '2025-01-01' and '2025-12-31' and o.status='completed' group by p.product_id,p.product_name,p.category,c.category_name having sum(oi.quantity)>100 order by revenue desc limit 20;

이 쿼리는 기술적으로 정확하지만 읽기에 악몽입니다. 이제 동일한 쿼리를 적절하게 포맷한 것을 보겠습니다:

SELECT 
    p.product_id,
    p.product_name,
    p.category,
    c.category_name,
    SUM(oi.quantity) AS total_sold,
    SUM(oi.quantity * oi.unit_price) AS revenue
FROM products p
JOIN categories c 
    ON p.category_id = c.category_id
JOIN order_items oi 
    ON p.product_id = oi.product_id
JOIN orders o 
    ON oi.order_id = o.order_id
WHERE o.order_date BETWEEN '2025-01-01' AND '2025-12-31'
    AND o.status = 'completed'
GROUP BY 
    p.product_id,
    p.product_name,
    p.category,
    c.category_name
HAVING SUM(oi.quantity) > 100
ORDER BY revenue DESC
LIMIT 20;

포맷된 버전은 쿼리의 구조를 즉시 드러냅니다. 네 개의 테이블을 조인하고, 날짜와 상태로 필터링하고, 제품 속성별로 그룹화하고, 결과를 상위 성과자로 제한한다는 것을 한눈에 볼 수 있습니다.

복잡한 서브쿼리 분해하기

서브쿼리와 공통 테이블 표현식(CTE)을 다룰 때 포맷팅은 훨씬 더 중요해집니다. 다음 예제를 고려하세요:

WITH monthly_sales AS (
    SELECT 
        DATE_TRUNC('month', order_date) AS month,
        customer_id,
        SUM(total_amount) AS monthly_total
    FROM orders
    WHERE order_date >= '2025-01-01'
    GROUP BY DATE_TRUNC('month', order_date), customer_id
),
customer_segments AS (
    SELECT 
        customer_id,
        AVG(monthly_total) AS avg_monthly_spend,
        CASE 
            WHEN AVG(monthly_total) >= 1000 THEN 'Premium'
            WHEN AVG(monthly_total) >= 500 THEN 'Standard'
            ELSE 'Basic'
        END AS segment
    FROM monthly_sales
    GROUP BY customer_id
)
SELECT 
    cs.segment,
    COUNT(DISTINCT cs.customer_id) AS customer_count,
    AVG(cs.avg_monthly_spend) AS avg_spend,
    SUM(ms.monthly_total) AS total_revenue
FROM customer_segments cs
JOIN monthly_sales ms 
    ON cs.customer_id = ms.customer_id
GROUP BY cs.segment
ORDER BY total_revenue DESC;

이 쿼리는 CTE를 사용하여 복잡한 분석을 논리적 단계로 분해합니다. 포맷팅은 각 단계를 명확하게 만들어 monthly_sales가 customer_segments로 공급되고, 그런 다음 최종 결과를 생성하는 방법을 보여줍니다.

SQL 포맷터 도구의 도움 받기

SQL을 수동으로 포맷할 수도 있지만, 자동화된 도구는 엄청난 시간을 절약하고 일관성을 보장합니다. 사용 가능한 다양한 유형의 SQL 포맷터를 살펴보겠습니다.

온라인 SQL 포맷터

RunDev의 SQL 포맷터와 같은 웹 기반 포맷터는 설치 없이 즉시 포맷팅을 제공합니다. 쿼리를 붙여넣고 버튼을 클릭하면 아름답게 포맷된 SQL을 받습니다. 이러한 도구는 빠른 포맷팅 작업이나 소프트웨어를 설치할 수 없는 컴퓨터에서 작업할 때 완벽합니다.

온라인 포맷터는 일반적으로 다음을 제공합니다:

IDE 확장 및 플러그인

대부분의 최신 코드 편집기는 확장을 통해 SQL 포맷팅을 지원합니다. Visual Studio Code, IntelliJ IDEA, DataGrip은 모두 개발 워크플로우에 직접 통합되는 강력한 SQL 포맷팅 기능을 제공합니다.

이러한 도구는 다음을 제공합니다:

명령줄 도구

자동화 및 CI/CD 파이프라인의 경우, sqlparse Python 라이브러리의 일부인 sqlformat 또는 PostgreSQL용 pg_format과 같은 명령줄 포맷터를 사용하면 일괄 작업으로 SQL 파일을 포맷할 수 있습니다.

빠른 팁: 커밋된 모든 SQL이 적절하게 포맷되도록 프리커밋 훅에 SQL 포맷팅을 추가하세요. 이렇게 하면 포맷팅 불일치가 코드베이스에 들어가는 것을 방지할 수 있습니다.

데이터베이스 관리 도구

DBeaver, SQL Server Management Studio, MySQL Workbench와 같은 도구에는 내장 포맷터가 포함되어 있습니다. 데이터베이스 관리 또는 쿼리 개발을 위해 이러한 환경에서 이미 작업하고 있을 때 편리합니다.

다양한 SQL 포맷팅 스타일 설명

프로그래밍 언어에 다양한 스타일 가이드가 있는 것처럼(JavaScript의 경우 Google 스타일 가이드 대 Airbnb 생각), SQL에도 여러 허용되는 포맷팅 규칙이 있습니다. 이를 이해하면 팀에 적합한 스타일을 선택하는 데 도움이 됩니다.

스타일 측면 옵션 A 옵션 B 권장사항
키워드 대소문자 대문자 소문자 더 나은 구분을 위한 대문자
쉼표 위치 후행(줄 끝) 선행(줄 시작) 친숙함을 위한 후행
들여쓰기 2칸 4칸 명확성을 위한 4칸
JOIN 정렬 테이블과 같은 줄 새 줄, 들여쓰기 복잡한 쿼리의 경우 새 줄
열 목록 줄당 하나 줄당 여러 개

📚 You May Also Like