Diff SQL: Compara Dos Archivos SQL Online
Pega, formatea y compara dos consultas SQL o archivos de esquema lado a lado. Funciona con PostgreSQL, MySQL, SQL Server, SQLite y Oracle.
¿Qué es la herramienta de diff SQL?
Una herramienta gratuita en el navegador para comparar dos archivos SQL. Pega un CREATE TABLE antiguo a la izquierda, el nuevo a la derecha, y los cambios se iluminan carácter por carácter. Mismo flujo para dos versiones de una consulta analítica, una sentencia generada por un ORM, o la salida de un pg_dump. Nada sale de tu máquina.
El diff es a nivel de texto. No parsea el SQL en un AST y no entiende equivalencia semántica: SELECT a, b y SELECT b, a se leen como distintos para el diff aunque ambos devuelvan las mismas filas en otro orden. Para el 95% de las tareas de revisión de código (migraciones de esquema, refactor de consultas, comparación de salida de ORM) el diff de texto es lo que realmente quieres, porque el orden de columnas y cláusulas es parte de cómo el equipo lee el cambio.
Si alguna vez has intentado encontrar la única cláusula WHERE nueva en una consulta analítica de 400 líneas que empezó a devolver un conteo de filas distinto, esta es la herramienta que te lleva ahí en segundos. Para prosa que no sea SQL, nuestra herramienta de diff de texto es la opción correcta. Para payloads de resultados de ORM en JSON, JSON diff maneja el reordenamiento de objetos con más limpieza. Para exportaciones DDL antiguas escritas como metadatos XML, XML diff encaja mejor.
Cómo funciona el diff en realidad
Por dentro el diff corre a nivel de carácter, y luego una pasada semántica desplaza los resaltados para que aterricen sobre identificadores, palabras clave y límites de cláusula en lugar de sobre puntuación arbitraria. Las inserciones se ven en verde a la derecha, las eliminaciones en rojo a la izquierda. Cada panel tiene un botón Format que reformatea el SQL con sangría consistente y una sentencia por línea, lo que mata casi todo el ruido de formato antes de comparar.
SQL es una familia de dialectos, no un único lenguaje. El estándar ISO/IEC 9075 define una gramática base, pero cada base de datos la extiende: PostgreSQL tiene strings con dollar-quoting y RETURNING, MySQL tiene identificadores con backtick y ON DUPLICATE KEY UPDATE, SQL Server usa TOP e identificadores entre corchetes, SQLite tolera casi cualquier cosa, y Oracle tiene ROWNUM y CONNECT BY. Hacer diff entre dialectos no es problema; la herramienta no te avisará de que un fragmento es inválido en alguno de ellos.
La otra cosa a saber: comparar el texto de una consulta no es lo mismo que comparar sus planes. Dos sentencias con texto idéntico pueden producir planes muy distintos con estadísticas distintas, y dos sentencias cosméticamente diferentes pueden producir el mismo plan. Para comparar planes, las herramientas correctas son EXPLAIN ANALYZE en psql o el equivalente en tu cliente de base de datos (DataGrip, DBeaver, SSMS). Para revisión de refactor a nivel de texto, el diff es lo que quieres. Lectura de fondo sobre el lenguaje, en Wikipedia.
Cómo comparar SQL en tres pasos
Dos paneles de texto, un diff. Sin registro, sin subida, sin ida y vuelta al servidor.
- 1
Pega o sube tu SQL
Pega el SQL antiguo a la izquierda, el nuevo a la derecha. O pulsa Subir en cualquiera de los lados para cargar directamente un archivo .sql, .ddl o .psql. El botón Ejemplo rellena ambos paneles con un pequeño esquema de orders si quieres ver primero la herramienta en acción.
- 2
Formatea ambos lados para una comparación justa
Pulsa Format en cada panel para reformatear el SQL con sangría consistente, una sentencia por línea y palabras clave en mayúsculas. Esto mata el ruido de una consulta formateada por DataGrip a un lado y otra escrita a mano al otro, así el diff resalta cambios reales de esquema y de cláusulas en lugar de diferencias de espacios y mayúsculas/minúsculas.
- 3
Lee el diff
Las eliminaciones aparecen en rojo a la izquierda, las inserciones en verde a la derecha. Si haces scroll en un lado, el otro le sigue. Los contadores de cambios en cada cabecera te dicen cuántas ediciones distintas encontró el diff entre columnas, joins, predicados y elementos DDL.
Cuándo el diff SQL es la herramienta adecuada
Revisar una migración de esquema antes de aplicarla
Un PR de migración añade tres columnas y ajusta dos índices. Pega el CREATE TABLE anterior contra el nuevo y las adiciones saltan a la vista: se añadió una columna currency CHAR(3) NOT NULL sin DEFAULT, lo que fallará en cualquier fila existente. Cazar eso antes de que la migración corra contra producción, y no después de que salte la alarma de despliegue a las 2 de la mañana, es el sentido completo de este flujo. Mismo valor para sentencias ALTER TABLE donde el tipo de una columna pasa de VARCHAR(255) a VARCHAR(50).
Diff de dos versiones de una consulta analítica
Una consulta de reporting que ayer devolvía 12.400 filas hoy devuelve 8.900. Haz diff de la consulta guardada de ayer contra la de hoy y el cambio culpable aflora: un LEFT JOIN se convirtió silenciosamente en INNER JOIN, o se añadió un WHERE status <> 'cancelled' por alguien intentando limpiar el dashboard. El diff de texto te lleva a la línea en segundos, donde leer ambas consultas lado a lado en Slack llevaría diez minutos.
Comparar SQL generado por ORM entre versiones de la app
Tras un upgrade de Hibernate o SQLAlchemy, consultas que antes eran tres joins ahora son cuatro con subconsultas extra, o el binding de parámetros pasó de ? a placeholders $1. Captura el SQL desde el log de consultas de cada versión de la app (log_statement = all en psql, slow log de MySQL, o tu herramienta de APM) y haz diff. Los nombres de alias serán ruidosos (t1, t2, generatedAlias0), pero el cambio estructural real suele ser lo único que el diff resalta como edición de verdad.
Validar que un refactor DDL preserva la intención
Renombraste user_orders a orders y dividiste una columna JSON en tablas normalizadas. Pega la salida de pg_dump --schema-only antes y después del refactor; el diff hace obvio si preservaste cada constraint, índice y default. La trampa a vigilar es un NOT NULL que desapareció silenciosamente durante el rename, o una constraint UNIQUE que se cayó porque nadie la volvió a añadir en la tabla nueva.
Comprobar que el esquema de staging coincide con prod
Ejecuta pg_dump --schema-only --no-owner contra staging y prod, y haz diff de los dos. Las diferencias deberían ser exactamente las migraciones encoladas para el próximo despliegue. Cualquier otra cosa, un índice extra, un tipo de columna distinto, una tabla de prueba olvidada, es señal de drift de esquema que morderá durante el despliegue real. Mismo enfoque con mysqldump --no-data para MySQL y SCRIPT TO para SQL Server, o el export de esquema de DataGrip en cualquier base de datos.
Revisar portado entre dialectos (Postgres a MySQL)
Portar una consulta de PostgreSQL a MySQL o al revés implica trackear qué funciones, tipos y cláusulas necesitan cambiar: SERIAL versus AUTO_INCREMENT, NOW() versus CURRENT_TIMESTAMP, RETURNING versus LAST_INSERT_ID(). Haz diff del original contra la versión portada y todas las sustituciones de dialecto afloran. El diff no validará el SQL en el dialecto de destino, así que pásalo igualmente por psql o mysql para confirmar, pero la vista línea a línea te dice qué decisiones revisar dos veces.
Referencia rápida de SQL
Una breve chuleta de los casos límite de dialecto y parseo que este diff saca a la luz con más frecuencia. Fundamentado en el estándar ISO SQL y en la documentación de los principales fabricantes.
| Topic | What this tool does |
|---|
| Drift de dialecto | PostgreSQL, MySQL, SQL Server, SQLite y Oracle extienden cada uno el estándar ISO SQL con su propia sintaxis. SERIAL, AUTO_INCREMENT, IDENTITY y GENERATED ALWAYS AS IDENTITY son cuatro formas de escribir la misma idea. |
|---|
| Plegado de mayúsculas en identificadores | PostgreSQL pliega los identificadores no entrecomillados a minúsculas, así que Users y users son la misma tabla. MySQL depende de lower_case_table_names y del filesystem subyacente. SQL Server es case-insensitive por defecto pero respeta la collation. Entrecomilla identificadores con "Users" (estándar), backticks (MySQL) o corchetes (SQL Server) para preservar el caso. |
|---|
| Capitalización de palabras clave | Las palabras clave SQL son case-insensitive en todas partes, así que SELECT y select son idénticas para el parser. La convención es mayúsculas para palabras clave y minúsculas para identificadores; la mayoría de guías de estilo y la spec ISO la siguen. El caso mixto es válido y ejecuta, pero herramientas como sqlfluff y sqlfmt lo normalizan. |
|---|
| Estilos de comentarios | Dos formas: -- comentario de línea (termina al final de la línea) y /* comentario de bloque */ (sin anidamiento en el SQL estándar, aunque algunos dialectos lo permiten). MySQL también soporta # para comentarios de línea como extensión. El diff trata los comentarios como texto y mostrará ediciones de comentarios igual que cualquier otro cambio. |
|---|
| Separadores de sentencias | El punto y coma (;) termina una sentencia en SQL estándar. La mayoría de clientes lo requieren entre sentencias en un script. Algunos clientes (SSMS) usan GO como separador de batch en su lugar, lo cual no es parte de la gramática SQL; es una directiva de cliente. |
|---|
| Strings con dollar-quoting (PostgreSQL) | PostgreSQL soporta $tag$ ... $tag$ para literales de string, así no necesitas escapar comillas simples dentro, especialmente útil en cuerpos de funciones. $$ SELECT 'hello' $$ es válido y común en bloques CREATE FUNCTION. Otros dialectos no parsean esta sintaxis. |
|---|
| Placeholders de binding de parámetros | No hay estándar. PostgreSQL y los ORM que lo apuntan usan $1, $2. JDBC, MySQL y ODBC usan ?. Los placeholders nombrados :name son comunes en Oracle y en muchas plantillas de string de ORM. El SQL generado por ORM entre versiones suele diferir solo en estilo de placeholder; formatea ambos lados antes de hacer diff. |
|---|
| Codificación | UTF-8 es el default universal para archivos SQL en 2026. Scripts antiguos de origen Windows todavía pueden estar guardados como UTF-16 LE con BOM, lo que aparece como un carácter fantasma en la línea 1 de un diff de texto. Si dos archivos parecen idénticos pero el diff marca un cambio de un carácter al inicio, sospecha del BOM y vuelve a guardar con UTF-8 explícito. |
|---|
Diff SQL: preguntas frecuentes
¿En qué se diferencia esto de correr EXPLAIN ANALYZE en ambas consultas?
Capa distinta del stack. EXPLAIN ANALYZE te muestra el plan de la consulta, lo que el optimizador decidió hacer dadas las estadísticas que tiene. Esta herramienta hace diff del texto de la consulta, que es lo que cambió en tu repo. Normalmente quieres ambas: este diff para detectar el refactor (cambió un tipo de join, se movió un predicado), y luego EXPLAIN ANALYZE en psql o tu cliente para confirmar que el optimizador eligió un plan razonable para la nueva forma. Las dos son complementarias, no sustitutas.
¿El diff es consciente del dialecto (PostgreSQL vs MySQL vs SQL Server)?
No. El diff trata la entrada como texto, así que no parsea PostgreSQL, MySQL, SQL Server, SQLite u Oracle de forma distinta y no marca sintaxis incompatible entre dialectos. Es a propósito: significa que puedes hacer diff entre dialectos, que es justo lo que quieres al portar una consulta. Si necesitas linting consciente de dialecto, pasa el SQL por sqlfluff o por el parser de tu base de datos por separado. Para el caso de revisión ("qué cambió en esta consulta"), el nivel de texto es la granularidad correcta.
¿La herramienta formatea el SQL por mí?
Sí, el botón Format de cada panel reformatea el SQL con sangría consistente, palabras clave en mayúsculas y una sentencia por línea. Es un formateador básico, no un reemplazo de sqlfmt o sqlfluff: no reescribe joins implícitos a explícitos, y no impone la guía de estilo de un dialecto concreto. La idea es matar el ruido de formato antes del diff, para que una consulta formateada por DataGrip a un lado y una escrita a mano al otro comparen limpias.
¿Normaliza la capitalización de palabras clave (SELECT vs select)?
El botón Format pone las palabras clave en mayúsculas, que es la convención en la mayoría de guías de estilo y en el estándar ISO SQL. Si no pulsas Format, el caso mixto aparece como diff porque el motor subyacente es a nivel de carácter. Las palabras clave SQL son case-insensitive en toda base de datos, así que select y SELECT ejecutan idéntico. La capitalización de identificadores es otra cuestión y varía por base de datos; mira la referencia rápida abajo para ver cómo difieren Postgres, MySQL y SQL Server.
¿Cómo lidio con alias generados por ORM como t1, t2, generatedAlias0?
La salida de un ORM es ruidosa por diseño: Hibernate genera generatedAlias0, generatedAlias1, y SQLAlchemy usa anon_1, anon_2. Si dos versiones de un ORM asignan los mismos alias en orden distinto, el diff de texto resaltará cada intercambio de alias como cambio aunque la consulta sea estructuralmente idéntica. El arreglo práctico es formatear ambos lados, ignorar las diferencias solo de alias (suelen ser obvias como pares de bloques rojos y verdes en la misma línea), y centrarse en las ediciones estructurales reales: un join nuevo, una cláusula WHERE distinta, una columna eliminada.
¿Hay límites de tamaño en el SQL que pego?
Límites blandos, no duros. El diff corre en tu navegador, así que el techo es la memoria del navegador y cuánto estés dispuesto a esperar. Una salida de pg_dump de 5.000 líneas hace diff en bastante menos de un segundo en un portátil moderno. Un dump de 200.000 líneas puede tardar varios segundos y rozar límites de memoria en dispositivos modestos. Para dumps de base de datos así de grandes, el flujo correcto es hacer diff schema-only primero (pg_dump --schema-only) y luego entrar en tablas concretas si necesitas comparación a nivel de datos.
Privacidad y cómo funciona
Tu SQL nunca sale de tu navegador. El formateador y el diff corren los dos en tu máquina, en local. Sin analítica de tu input, sin logs, sin viaje al cloud "para ayudar", lo cual importa cuando el SQL que pegas contiene nombres reales de tablas, nombres reales de columnas o datos reales de producción en una fila de muestra. El lenguaje está documentado en ISO/IEC 9075, y las referencias de dialecto son PostgreSQL, MySQL, SQL Server y SQLite.