SQL 포맷 도구
SQL 서식 정리란?
SQL 서식 정리는 압축되거나 정리되지 않은 SQL 문을 들여쓰기가 정돈되고 키워드가 두드러져 읽기 쉬운 형식으로 변환하는 것입니다. 우수한 SQL 서식 정리는 코드 가독성을 향상시키고 팀 협업 검토를 용이하게 하며 쿼리 로직과 조건을 빠르게 파악할 수 있게 합니다. 데이터베이스 개발과 유지보수에 필수적인 기술입니다. 서식 정리는 쿼리를 읽기 쉽게 만들지만 실행 계획이나 성능을 자동으로 개선하지는 않습니다. 복잡한 SQL은 인덱스, 조인 조건, 데이터베이스 방언까지 함께 검토해야 합니다.
사용 방법
사용 방법
- 왼쪽 입력 영역에 SQL 문을 붙여넣거나 입력하세요.
- 들여쓰기 크기(2칸, 4칸, Tab)와 키워드 대소문자 방식을 선택하세요.
- '서식 정리'를 클릭해 SQL을 정돈하거나, '압축'을 클릭해 공백을 제거하세요.
- 구문 강조가 적용된 결과가 오른쪽에 표시됩니다.
- '복사' 또는 '다운로드'를 클릭해 결과를 저장하세요.
SQL 검토 시 참고사항
- 정렬은 가독성을 높이지만 권한, 인덱스, 실행 계획, 비즈니스 로직의 정확성은 검증하지 않습니다.
- 변경된 SQL 실행 전 생성된 절, 문자열 리터럴, 주석, DB별 구문을 수동으로 확인하세요.
활용 사례
기술 원리
프린터 단계에서는 절마다 하나의 규칙을 적용합니다. SELECT / FROM / WHERE / GROUP BY / HAVING / ORDER BY / LIMIT은 각각 0열에서 새 줄을 시작하고, 투영된 열과 ON 조건은 한 단계 들여쓰기(2칸, 4칸 또는 탭), JOIN 키워드(INNER / LEFT / RIGHT / FULL / CROSS)는 FROM 아래에 정렬, CASE / WHEN / THEN / ELSE / END는 수직으로 쌓고, 괄호로 묶인 서브쿼리와 WITH 안의 CTE는 추가 들여쓰기 레벨을 받아 외부 SELECT가 시각적으로 고정됩니다. 문자열 리터럴, 줄 주석(-- ...), 블록 주석(/* ... */), 달러 인용 블록은 한 번 토큰화한 후 그대로 복사하므로 내부 공백은 절대 건드리지 않습니다.
키워드 대소문자는 소스에 대해 무작정 정규식을 적용하는 것이 아니라 프린터 단계에서 적용됩니다. RESERVED_KEYWORD로 분류된 토큰만 UPPER 또는 lower로 변환되므로, 백틱 안의 'order'나 'user' 같은 식별자는 원래 대소문자를 유지합니다. 방언 지원이 중요한 이유는 예약어 목록이 엔진마다 다르기 때문입니다. PostgreSQL은 DISTINCT ON, RETURNING, ILIKE를 인식하고, MySQL은 IFNULL, LIMIT n,m, ENGINE=을 추가하며, SQL Server는 TOP n, OUTPUT, 대괄호 식별자를 사용하고, Oracle은 DUAL, ROWNUM, EXCEPT 대신 MINUS를 사용하며, BigQuery와 Snowflake는 QUALIFY, EXCEPT(열), 배열/구조체 리터럴로 표준을 확장합니다. 성능은 소스 길이에 비례합니다(O(n) 토큰, O(n) 출력 바이트). 수 메가바이트 마이그레이션 스크립트도 밀리초 단위로 서식이 정리됩니다.
- 토크나이저: 소스를 RESERVED_KEYWORD, IDENTIFIER, STRING_LITERAL, NUMBER, OPERATOR, LINE_COMMENT(-- ...), BLOCK_COMMENT(/* ... */), WHITESPACE 클래스로 스캔; 주석과 문자열은 그대로 보존
- 방언 인식: 작은따옴표 문자열(ANSI), 백틱 식별자(MySQL), 대괄호 식별자(SQL Server), 큰따옴표 식별자(PostgreSQL/표준), 달러 인용 블록 $$...$$(PostgreSQL)
- 절 레이아웃: SELECT, FROM, WHERE, GROUP BY, HAVING, ORDER BY, LIMIT은 각각 0열에 고정; 투영된 열과 ON 조건은 한 단계 들여쓰기; JOIN 키워드는 FROM 아래에 정렬
- CTE 및 서브쿼리 들여쓰기: WITH 절은 내부 SELECT를 한 단계 더 들여쓰기; EXISTS / IN / 스칼라 컨텍스트의 상관 서브쿼리는 자체 들여쓰기를 받아 외부 쿼리가 고정된 위치를 유지
- 대소문자 정책: 프린터 단계에서 토큰 클래스별로 적용; RESERVED_KEYWORD 토큰만 대/소문자 변환하므로 `order` 또는 [user] 같은 식별자는 원래 대소문자 유지
- 바인드 매개변수: 물음표 플레이스홀더(MySQL prepared statement), 달러1/달러2 번호 바인딩(PostgreSQL), 콜론 이름 바인딩(Oracle/SQL*Plus)은 PARAMETER로 토큰화되어 식별자로 재서식되지 않음
- 복잡도: O(n) 렉싱 및 O(n) 프린팅(n = 소스 길이); 수 메가바이트 마이그레이션 스크립트도 밀리초 단위로 서식 정리; sql-formatter npm 라이브러리, pgFormatter, Prettier SQL 플러그인과 동등한 성능
예시
JOIN과 WHERE이 포함된 압축된 SELECT 포맷팅
입력: select u.id,u.name,o.total from users u left join orders o on o.user_id=u.id where u.status='active' and o.created_at>='2026-01-01' order by o.total desc limit 10;
출력:
SELECT u.id, u.name, o.total
FROM users u
LEFT JOIN orders o ON o.user_id = u.id
WHERE u.status = 'active'
AND o.created_at >= '2026-01-01'
ORDER BY o.total DESC
LIMIT 10;설정 문자열용 SQL 압축
입력 (포맷됨, 6줄):
SELECT id, name
FROM products
WHERE price < 100
AND stock > 0
ORDER BY name;
압축 출력 (1줄, 78자):
SELECT id,name FROM products WHERE price<100 AND stock>0 ORDER BY name;WITH (CTE) + 중첩 서브쿼리 포맷팅
WITH recent_orders AS (
SELECT user_id, SUM(total) AS spend
FROM orders
WHERE created_at >= NOW() - INTERVAL '30 days'
GROUP BY user_id
)
SELECT u.name, r.spend
FROM users u
JOIN recent_orders r ON r.user_id = u.id
WHERE r.spend > (SELECT AVG(spend) FROM recent_orders);키워드 소문자 (팀 컨벤션)
설정: 들여쓰기 = 공백 2칸, 키워드 = 소문자
입력: SELECT * FROM Users WHERE Status=1;
출력:
select *
from users
where status = 1;
용도: Ruby on Rails / Django ORM 스타일의 마이그레이션 파일과 일치자주 묻는 질문
어떤 SQL 방언을 지원하나요?
표준 ANSI SQL과 함께 주요 방언별 키워드를 지원합니다. MySQL, PostgreSQL, MSSQL/T-SQL, SQLite, Oracle, BigQuery, Snowflake가 포함됩니다. 드롭다운에서 대상 방언을 선택하면 LIMIT 대 TOP, RETURNING, MERGE 같은 방언 고유 키워드를 올바르게 처리합니다.
어떤 스타일 옵션이 있나요?
키워드 대문자/소문자, 들여쓰기 크기, 컬럼 목록의 선행/후행 콤마, 줄바꿈 기준 최대 길이, 키워드 앞에서 줄을 바꿀지 뒤에서 바꿀지 등을 설정할 수 있습니다. 보통 사이드 패널에서 옵션을 확인할 수 있습니다.
SQL 유효성 검사도 해 주나요?
대부분의 포매터는 느슨하게 파싱하기 때문에 의심스러운 SQL도 그대로 통과시킵니다. 실제 검증에는 데이터베이스 연결 또는 sqlparse, sqlglot 같은 본격적인 SQL 파서가 필요합니다. 이 도구는 레이아웃 정리에 사용하시고, 문법 검사는 IDE나 실제 데이터베이스에서 진행하세요.
저장 프로시저나 트리거도 포매팅되나요?
대부분의 빌드는 방언이 지원하는 범위 내에서 CREATE PROCEDURE, CREATE FUNCTION, 트리거를 처리합니다. IF/ELSE/WHILE 같은 제어 흐름이 포함된 긴 본문도 올바르게 정리되지만, 벤더 확장(T-SQL 고유 키워드 등)은 해당 방언을 정확히 지정해야 합니다.
쿼리가 서버로 업로드되나요?
아니요. 포매팅은 JavaScript SQL 파서를 이용해 브라우저에서만 실행되며, 붙여넣은 SQL은 전송되지 않습니다. 그렇더라도 실제 운영 자격증명이나 개인정보는 어떤 웹 도구에도 붙여넣지 마세요.
CTE와 JOIN의 들여쓰기가 이상하게 보이는 이유는 무엇인가요?
CTE 정렬 방식은 포매터마다 의견이 다릅니다. 각 CTE 정의를 들여쓰는 방식도 있고, 왼쪽에 붙이는 방식도 있습니다. JOIN도 'JOIN x ON' vs 'JOIN x\n ON'처럼 여러 가지 유효한 스타일이 있습니다. 팀 스타일에 맞는 옵션을 골라 일관되게 사용하세요.
SQL을 한 줄로 압축할 수도 있나요?
일부 빌드는 줄바꿈과 공백을 모두 제거하는 'one-line' 모드를 제공합니다. SQL을 코드 안에 문자열 리터럴로 삽입할 때 유용합니다. 다만 한 줄짜리 SQL은 코드 리뷰가 어렵기 때문에 버전 관리에는 항상 정렬된 버전을 보관하세요.