Formateador SQL
Formatea consultas SQL o compáctalas en una sola línea
Procesando…
0.0
No se ha bloqueado: el resultado aparecerá cuando termine el cálculo.
Acerca de Formateador SQL
Este formateador no es un analizador sintáctico de SQL. Divide el texto en tokens, palabras clave, identificadores, números, cadenas, comentarios y signos, y aplica reglas de salto de línea: una línea nueva para cada cláusula como SELECT, FROM, WHERE, JOIN o GROUP BY, las palabras clave conocidas en mayúsculas, un elemento por línea en la lista del SELECT y una línea por cada AND/OR del WHERE. Las cadenas entre comillas simples y los comentarios no se tocan.
Al no analizar la consulta, no sabe si es válida y no conoce todos los dialectos. A continuación se indica qué sintaxis propia de MySQL, PostgreSQL y SQL Server conserva intacta y qué problemas no se arreglan con sangría.
Qué sintaxis de cada dialecto reconoce
En SQL estándar las comillas simples delimitan cadenas y las dobles delimitan identificadores, y una comilla dentro de una cadena se duplica: 'It''s'. La herramienta entiende eso, los identificadores con acento grave de MySQL, como `id`, y las características de dialecto siguientes, que mantiene como un solo token.
- Las cadenas de MySQL con barra invertida, como 'It\'s', se conservan tal cual. Si al leer las barras como escape la cadena quedara sin cerrar, la herramienta vuelve a la regla estándar ('').
- El comentario de línea # de MySQL se reconoce. Al minificar se elimina como cualquier otro comentario, así que la línea siguiente no queda absorbida. Los operadores #>, #>> y #- de PostgreSQL se tratan como operadores, no como comentarios.
- Los operadores ->>, ->, @>, <@, || y el :: de PostgreSQL se mantienen enteros; :: se escribe sin espacios, como en created_at::date. Los cuerpos entre $$ ... $$ o $tag$ ... $tag$ se tratan como cadenas y no se tocan.
- Los signos pegados a una cadena conservan su espaciado original: array['a'] queda igual.
- Los identificadores entre corchetes de SQL Server, como [order id], se conservan tal cual, espacios incluidos.
- Al minificar se eliminan los comentarios -- y /* */, pero se conservan las pistas del optimizador (/*+ ... */) y los comentarios ejecutables /*! ... */ de MySQL, porque cambian cómo se ejecuta la consulta.
Lo que el formato no puede arreglar
La trampa clásica es la precedencia. AND se evalúa antes que OR, así que a = 1 OR b = 2 AND c = 3 significa a = 1 OR (b = 2 AND c = 3). El formateador coloca AND y OR a la misma profundidad, lo que invita a leer las tres condiciones como equivalentes. Si querías (a = 1 OR b = 2) AND c = 3, tienes que poner los paréntesis tú.
Lo mismo pasa con un LEFT JOIN filtrado en el WHERE. En el primer ejemplo, la condición sobre o.created_at se aplica después de la unión; para los usuarios sin pedidos o.created_at es NULL, la comparación no es verdadera y esas filas desaparecen. La consulta se comporta en silencio como un INNER JOIN. Para conservar a los usuarios sin pedidos, mueve la condición a la cláusula ON. Un buen formato ayuda a verlo, pero la herramienta no lo señala.
Del mismo modo, col = NULL da 'desconocido' y nunca selecciona filas; hace falta IS NULL. Una consulta con ese error es SQL válido antes y después de formatearla.
Qué cambia la herramienta y qué no
- Solo pasan a mayúsculas las palabras de su lista: SELECT, FROM, LEFT JOIN, GROUP BY, CASE, AS, etc. Los nombres de funciones y tipos como count, coalesce o date quedan como los escribiste.
- El ancho de sangría se fija en espacios. Las subconsultas se sangran un nivel más por cada paréntesis.
- Minificar reduce los espacios a uno y elimina los comentarios (salvo las pistas /*+ */ y los /*! */). Los espacios repetidos dentro de cadenas, como 'x y', se conservan.
Ejemplos
Ordenar una consulta de una línea
- Entrada
select u.id, u.name, count(o.id) as cnt from users u left join orders o on o.user_id = u.id where u.active = 1 and o.created_at >= '2026-01-01' group by u.id, u.name having count(o.id) > 3 order by cnt desc limit 10;- Resultado
SELECT u.id, u.name, count(o.id) AS cnt FROM users u LEFT JOIN orders o ON o.user_id = u.id WHERE u.active = 1 AND o.created_at >= '2026-01-01' GROUP BY u.id, u.name HAVING count(o.id) > 3 ORDER BY cnt DESC LIMIT 10;
Una vez ordenada, se ve que la condición sobre o.created_at en el WHERE convierte el LEFT JOIN, en la práctica, en una unión interna.
AND y OR a la misma altura
- Entrada
select * from t where a = 1 or b = 2 and c = 3- Resultado
SELECT * FROM t WHERE a = 1 OR b = 2 AND c = 3
El significado real es a = 1 OR (b = 2 AND c = 3). No deduzcas la lógica por la disposición de las líneas.
Operadores de PostgreSQL intactos
- Entrada
select id, data->>'name' as n, created_at::date from t where tags @> array['a']- Resultado
SELECT id, data ->>'name' AS n, created_at::date FROM t WHERE tags @> array['a']
->>, :: y @> quedan como un solo token cada uno. ->> está pegado a la cadena 'name', así que se conserva el espaciado original entre ambos.
Minificar con una pista y un comentario #
- Entrada
SELECT /*+ INDEX(o idx_user) */ id FROM o # note WHERE a = 1- Resultado
SELECT /*+ INDEX(o idx_user) */ id FROM o WHERE a = 1
La pista del optimizador se conserva y solo se elimina el comentario # note. El WHERE de la línea siguiente queda intacto.
Cómo se usa
- Pega tu SQL. Separa las sentencias con punto y coma.
- Elige el ancho de sangría y pulsa Formatear o Minificar.
- Compara la salida con el original antes de usarla.
Preguntas frecuentes
¿Detecta errores de sintaxis?
No. Solo reorganiza tokens, así que una consulta inválida se formatea igual. Para comprobarla usa EXPLAIN o ejecútala en tu base de datos.
¿Por qué las funciones siguen en minúsculas?
Solo se pasan a mayúsculas las palabras de la lista interna de palabras clave. Funciones como count o coalesce quedan como las escribiste.
¿Puedo pegar el SQL minificado en mi código?
Sí, pero los comentarios normales se eliminan; solo se conservan las pistas (/*+ */) y los comentarios ejecutables de MySQL (/*! */). Además, minificar SQL apenas aporta rendimiento.
¿Admite los operadores de PostgreSQL?
Sí: ->>, ->, @>, <@, ||, :: y las cadenas con $$ se mantienen enteros. No hay ajustes por dialecto, así que compara la salida si usas otra sintaxis propia.
Fuentes
- MySQL 8.0 Reference Manual: Comments
- MySQL 8.0 Reference Manual: String Literals
- PostgreSQL: JSON Functions and Operators
- PostgreSQL: Operator Precedence
- Microsoft Learn: Database identifiers (SQL Server)
Revisado el: