DevFormatter

SQL Formatter

 

How it works

SQL (Structured Query Language) is the standard language for querying and manipulating relational databases. Every relational database — MySQL, PostgreSQL, SQLite, Oracle, SQL Server, BigQuery — uses SQL as its primary interface, though each dialect adds proprietary extensions and syntax variations.

This tool uses the sql-formatter JavaScript library to parse and reformat SQL entirely in your browser. No data is ever sent to a server. The library supports seven SQL dialects and enforces uppercase keywords — the widely adopted style that distinguishes SQL structure from data identifiers.

  • Beautify — parses your SQL and re-serializes it with consistent indentation and uppercase keywords. Rewrites the input box so you always see clean SQL.
  • Minify — collapses SQL to a single line for embedding in application code strings. Output only — input is unchanged.
  • Dialect — select the target database to get correct identifier quoting (backticks for MySQL, double quotes for PostgreSQL) and dialect-specific keyword handling.
  • Validate — the formatter catches syntax errors (mismatched parentheses, unclosed strings, unknown tokens) and reports them in the status bar.

SQL Quick Reference

Clause Purpose Example
SELECT Choose which columns to return SELECT id, name, email
FROM Specify the source table(s) FROM users
WHERE Filter rows before aggregation WHERE status = 'active'
JOIN Combine rows from multiple tables INNER JOIN orders ON users.id = orders.user_id
LEFT JOIN All left rows + matching right rows LEFT JOIN orders ON users.id = orders.user_id
RIGHT JOIN All right rows + matching left rows RIGHT JOIN orders ON users.id = orders.user_id
GROUP BY Aggregate rows by column values GROUP BY department
HAVING Filter groups after aggregation HAVING COUNT(*) > 5
ORDER BY Sort result rows ORDER BY created_at DESC
LIMIT / OFFSET Paginate results (MySQL/PostgreSQL) LIMIT 20 OFFSET 40
INSERT Add new rows to a table INSERT INTO users (name, email) VALUES ('Alice', '[email protected]')
UPDATE Modify existing rows UPDATE users SET status = 'active' WHERE id = 1
DELETE Remove rows from a table DELETE FROM users WHERE id = 1

SQL Dialect Differences

While ANSI SQL defines a common core, each database extends the language with proprietary syntax. Selecting the right dialect in the formatter ensures correct identifier quoting and keyword formatting for your target database.

Feature MySQL PostgreSQL T-SQL (SQL Server) PL/SQL (Oracle)
Identifier quoting `table` "table" [table] "table"
Top N rows LIMIT 10 LIMIT 10 TOP 10 / FETCH NEXT 10 FETCH FIRST 10 ROWS
String concat CONCAT(a, b) a || b a + b a || b
Auto-increment AUTO_INCREMENT SERIAL / GENERATED IDENTITY(1,1) GENERATED AS IDENTITY
JSON support JSON type, -> operator JSON / JSONB, -> ->> JSON_VALUE, OPENJSON JSON_VALUE (12c+)
Upsert syntax INSERT ... ON DUPLICATE KEY INSERT ... ON CONFLICT MERGE MERGE

Tips & Tricks

🏷

Dialect selector changes identifier quoting

Switch to MySQL to format backtick-quoted identifiers (`users`); switch to PostgreSQL for double-quote identifiers ("users"). The wrong dialect may reformat quoting incorrectly.

⚡

Minify before embedding in application code

Multi-line SQL in string literals makes code hard to read. Use Minify to collapse to a single line for embedding in Python, JavaScript, or Go source files, then add a comment pointing to the formatted version.

🔍

Uppercase keywords aid code reviews

When all SQL keywords are uppercase, reviewers can instantly distinguish structure (WHERE, JOIN) from schema identifiers (users, orders). Consistent formatting reduces cognitive load in pull requests.

📋

Use CTEs to break up complex queries

A WITH clause (CTE) names a subquery so you can reference it multiple times. The formatter indents CTEs clearly, making it much easier to follow multi-step data transformations than deeply nested subqueries.

⚙

T-SQL uses TOP instead of LIMIT

If you switch between MySQL/PostgreSQL and SQL Server, remember that SELECT TOP 10 * goes before the column list in T-SQL, while LIMIT 10 goes at the end in MySQL/PostgreSQL. Select the T-SQL dialect to format SQL Server queries correctly.

⚠

Always add WHERE before UPDATE or DELETE

UPDATE users SET active = 0 without a WHERE clause updates every row. Beautifying your query before running it helps catch missing WHERE clauses before they cause data loss.

Code Examples

Node.js — sql-formatter

import { format } from 'sql-formatter';

const formatted = format(
  'select id,name from users where active=1',
  {
    language: 'mysql',
    tabWidth: 2,
    keywordCase: 'upper',
    linesBetweenQueries: 1,
  }
);
console.log(formatted);
// SELECT
//   id,
//   name
// FROM
//   users
// WHERE
//   active = 1

Python — sqlparse

import sqlparse

sql = 'select id,name from users where active=1'
formatted = sqlparse.format(sql, reindent=True, keyword_case='upper')
print(formatted)
# SELECT id,
#        name
# FROM users
# WHERE active=1

# For more control use sqlparse.parse()
parsed = sqlparse.parse(sql)[0]
for token in parsed.tokens:
    print(token.ttype, repr(token))

CLI — pgFormatter & sqlfluff

# pgFormatter — format PostgreSQL / SQL files in place
pg_format --inplace query.sql

# Format and write to stdout
pg_format query.sql

# Use sqlfluff to lint and fix SQL
pip install sqlfluff
sqlfluff fix --dialect postgres query.sql

# Format SQL in a pipeline (Node.js npx)
echo "select id from users" | npx sql-formatter-cli --language mysql

Frequently Asked Questions

What is SQL?
SQL (Structured Query Language) is the standard language for querying and manipulating relational databases. It was first developed at IBM in the 1970s, standardized as ANSI SQL in 1986, and is now the universal interface to relational databases including MySQL, PostgreSQL, SQLite, Oracle, SQL Server, and BigQuery. SQL consists of four sublanguages: DML (SELECT, INSERT, UPDATE, DELETE), DDL (CREATE, ALTER, DROP), DCL (GRANT, REVOKE), and TCL (COMMIT, ROLLBACK).
What SQL dialects are supported?
The formatter supports Standard SQL, MySQL, PostgreSQL, SQLite, PL/SQL (Oracle), T-SQL (SQL Server), and BigQuery. Selecting the correct dialect matters because each database uses different identifier quoting (MySQL uses backticks, PostgreSQL uses double quotes, T-SQL uses square brackets), different pagination syntax, and dialect-specific functions and keywords.
Why does the formatter uppercase SQL keywords?
SQL keywords are case-insensitive in all major databases, but writing keywords in uppercase (SELECT, FROM, WHERE) and identifiers in lowercase (users, id, name) is the most widely adopted style in professional codebases and style guides. Uppercase keywords improve scannability — you can instantly distinguish language structure from data identifiers at a glance.
Is my SQL sent to a server?
No. All formatting, minification, and validation runs entirely in your browser using JavaScript. Your SQL queries never leave your machine and no account or sign-up is required. This makes the tool safe to use with sensitive production queries or proprietary schema names.
What is the difference between WHERE and HAVING?
WHERE filters rows before aggregation; HAVING filters groups after aggregation. WHERE cannot reference aggregate functions (COUNT, SUM, AVG, etc.) because those are computed after grouping. HAVING is always used with GROUP BY. Example: SELECT dept, COUNT(*) FROM employees WHERE salary > 50000 GROUP BY dept HAVING COUNT(*) > 5 — WHERE removes low-salary employees first, then HAVING removes small departments.
What is the difference between INNER JOIN and LEFT JOIN?
INNER JOIN returns only rows where the join condition matches in both tables — unmatched rows are excluded from the result. LEFT JOIN returns all rows from the left table plus matching rows from the right table; if no match exists, right-table columns are NULL. Use INNER JOIN when you need records with data in both tables. Use LEFT JOIN when you want all records from the primary table regardless of whether a related record exists.
What does SELECT * mean and should I avoid it?
SELECT * retrieves all columns from the table. It is convenient for ad hoc queries but should be avoided in production code: it fetches columns you may not need (increasing I/O and network transfer), breaks when columns are added or reordered in INSERT INTO ... SELECT * statements, and prevents the optimizer from using covering indexes.
How do I write comments in SQL?
SQL supports two comment styles. Single-line comments start with -- and extend to the end of the line. Block comments use /* ... */ and can span multiple lines. Both styles are preserved by the formatter. MySQL also supports # as a single-line comment delimiter, but this is non-standard and not recognized by other databases.
What is SQL injection and how do I prevent it?
SQL injection is an attack where malicious SQL is inserted through user-supplied input. If a query is built by string concatenation like WHERE username = '" + userInput + "'", an attacker can enter ' OR '1'='1 to bypass authentication. Prevention: always use parameterized queries (prepared statements) — in Python: cursor.execute('SELECT * FROM users WHERE id = %s', (user_id,)); in Node.js: db.query('SELECT * FROM users WHERE id = ?', [userId]).
What is a JOIN in SQL?
A JOIN combines rows from two or more tables based on a related column. The main types are: INNER JOIN (only matching rows from both tables), LEFT JOIN (all left rows + matching right rows), RIGHT JOIN (all right rows + matching left rows), FULL OUTER JOIN (all rows from both tables with NULLs for non-matches), and CROSS JOIN (Cartesian product of every row combination). Joins are fundamental to relational databases because data is stored in separate normalized tables.
Does the formatter validate my SQL?
Yes. The formatter uses the sql-formatter library to parse your SQL before reformatting it. If the SQL cannot be parsed — syntax errors, mismatched parentheses, unclosed string literals — it reports an error in the status bar. Note that sql-formatter performs syntactic validation only; it cannot verify that table names, column names, or functions exist in your database schema.
What is the difference between TRUNCATE and DELETE?
DELETE removes rows one at a time, logs each deletion, supports a WHERE clause, can be rolled back in a transaction, and fires DELETE triggers. TRUNCATE removes all rows by deallocating data pages — it is much faster for large tables, cannot be filtered with WHERE, does not fire row-level triggers, and cannot be rolled back in MySQL (though PostgreSQL and SQL Server do support TRUNCATE inside a transaction). Use DELETE for selective removal; use TRUNCATE to quickly empty an entire table.
What is a subquery in SQL?
A subquery is a SELECT statement embedded inside another SQL statement. Subqueries can appear in the SELECT list, FROM clause (derived tables), WHERE clause, or HAVING clause. Example: SELECT name FROM users WHERE id IN (SELECT user_id FROM orders WHERE total > 100). CTEs (WITH clauses) are often more readable than deeply nested subqueries and are supported in all major databases since SQL Server 2005 and MySQL 8.0.

Related Tools

Other free developer tools available on DevFormatter.