Skip to content
SQLCraft
  • 100% client-side isolated
  • no upload
  • gaps reported

Convert the dialect, and see what would break

Move one query between six SQL engines and get the spellings that actually differ — quoting, escaping, booleans, type names, auto-increment columns and LIMIT / TOP / FETCH FIRST. Whatever cannot be translated is listed, never dropped.

Examples
Re-format the resultLay it out with the target's rules

Source statement

Written for PostgreSQL.

1 lines
PG → MY

Converted

Spelled the way MySQL reads it.

SELECT
  id,
  name,
  payload -> 'ip' AS client_ip
FROM events
WHERE name ILIKE '%login%'
  AND created_at > now() - INTERVAL '7 days'
ORDER BY created_at DESC
LIMIT 20;
Rewrites
1
Notes
4
Warnings
2
Row cap
LIMIT n

What changed, and what cannot

A wrong translation is worse than a named gap, so nothing is left unsaid here.

1 rewrite · 2 warnings
  • MySQL JSON paths are functions: JSON_EXTRACT(col, '$.key').
  • MySQL has no ILIKE; use `LOWER(col) LIKE LOWER('…')` (the collation is usually case-insensitive already).
  • MySQL keeps an unquoted name exactly as it is written, so nothing had to be re-cased; the quoting above is only that dialect's own style.
  • String concatenation differs: PostgreSQL uses || and MySQL uses CONCAT.

2 informational notes describe a spelling that was replaced rather than a construct that is missing.

MySQL, in one card

What the converter had to respect while rewriting the statement.

Identifiers
`name`
Case folding
preserve
Booleans
1 / 0
Comments
-- #
Concat
CONCAT
Row cap
LIMIT n
UUID type
CHAR(36)
JSON type
JSON

Backticks quote identifiers, and a double-quoted string is a string rather than a name. `#` starts a comment, backslashes escape inside strings, and TRUE is stored as 1.

Auto-increment idiom for a generated primary key: AUTO_INCREMENT

Rewrite the spelling, never guess the meaning

Quoting, escaping, boolean literals, the CAST operator and the row-cap keywords are all spelling differences with exactly one correct answer per engine, so they are rewritten outright. Anything whose meaning would change — or which has no equivalent at all — is reported instead, so the output can be reviewed rather than trusted.

Row caps are the classic break

PostgreSQL and MySQL cap rows with LIMIT at the end, T-SQL needs TOP right after SELECT, and Oracle and Snowflake append FETCH FIRST n ROWS ONLY. A query that reads correctly in one engine silently returns everything in another, which is why the conversion moves the cap to the place the target actually accepts.

Types differ, and it says so

Oracle has no BOOLEAN column and becomes NUMBER(1); T-SQL has no JSON column and becomes NVARCHAR(MAX) holding text; SQLite has no native UUID and becomes a sized string. Every one of those substitutions is announced, because a silent change of type is a change of contract.

  • SQL Formatter

    Pretty-print a query with clause phrases on their own line, commas broken only inside a list and subqueries on their own indent — or collapse it back to one line. Keyword casing, indent width, leading or trailing commas and a line-length limit are all switches, and the token stream is compared before and after so a reformat can never rewrite the query.

    Open tool
  • JSON / CSV to SQL

    Paste an API response, one JSON object per line, or a CSV export and get a CREATE TABLE with types inferred from the values rather than declared up front: sizes come from the longest string, a date that meets a timestamp widens to a timestamp, and every substitution or renamed key is reported. The INSERT statements follow, batched or one per row.

    Open tool
  • Mock Data

    Pick a preset table — users, orders, products or subscriptions — set a row count and a seed, and get rows that hold together: an email built from the same row's names, a status from a small vocabulary, dates that never read the clock. Four presets, twenty-three column kinds and one identical result per seed.

    Open tool

Dialect conversion FAQ

What is rewritten, what is reported instead, how LIMIT becomes TOP, and where the six engines differ.

What exactly gets rewritten when I switch dialects?

Identifier quoting (double quotes for PostgreSQL, SQLite and Oracle, backticks for MySQL, brackets for T-SQL), string escaping (backslashes only where the dialect enables them), boolean literals (TRUE/FALSE against 1/0), the CAST spelling, the row-limit family (LIMIT, TOP, FETCH FIRST n ROWS ONLY), the `::` cast operator, the concat operator, and the type names used inside DDL and CAST expressions.

Why is a construct sometimes reported instead of converted?

Because a wrong translation is worse than a named gap. ILIKE has no direct T-SQL or Oracle equivalent, JSONB and its `->` operator exist only in PostgreSQL, QUALIFY is a Snowflake extension, and ON CONFLICT is written as ON DUPLICATE KEY or MERGE elsewhere. Each one is listed with the target it failed for, so the output can be reviewed instead of trusted.

How is LIMIT handled in both directions?

T-SQL needs TOP directly after SELECT, so a LIMIT arriving from PostgreSQL is moved up into a TOP clause. Going the other way, a TOP is moved to the end as a LIMIT. Oracle and Snowflake both accept FETCH FIRST n ROWS ONLY, which is appended instead of a LIMIT. When an OFFSET is present, the form the target actually supports is used.

Are the six dialects equal in what they support?

No, and the converter is built around that. Oracle has no boolean column type, so a boolean becomes NUMBER(1) and the substitution is reported. T-SQL has no JSON column, so JSON becomes NVARCHAR(MAX) holding text. SQLite has no native UUID type, so it becomes a sized character column. Those substitutions are always announced.

Does the output keep my formatting?

The conversion preserves the layout it can and offers to re-run the formatter for the target dialect afterwards. Re-formatting is worth doing when the target changes a keyword into two words (a LIMIT into FETCH FIRST, for instance), because the new spelling may need its own line break to stay readable.