Convert PostgreSQL to MySQL

A free online converter that translates PostgreSQL queries into MySQL. Paste your SQL, press Translate, and Query Studio rewrites the syntax that differs between the two databases — instantly, with no login and nothing stored.

The less-travelled direction, and the one worth questioning before you start. Most of the work is not translation but deciding what to do about the PostgreSQL features MySQL has no answer for — arrays, custom types, partial indexes and transactional DDL among them.

Open in the editor →All Query Studio tools

PostgreSQLMySQL example

Here is a real PostgreSQL query and the MySQL output Query Studio produces:

PostgreSQL input
SELECT u.id, u.name, COUNT(o.id) AS orders
FROM users u
LEFT JOIN orders o ON o.user_id = u.id
WHERE u.created_at > '2024-01-01' AND u.active = TRUE
GROUP BY u.id, u.name
HAVING COUNT(o.id) > 3
ORDER BY orders DESC
LIMIT 10;
MySQL output
SELECT
  u.id,
  u.name,
  COUNT(o.id) AS orders
FROM
  users u
  LEFT JOIN orders o ON o.user_id = u.id
WHERE
  u.created_at > '2024-01-01'
  AND u.active = TRUE
GROUP BY
  u.id,
  u.name
HAVING
  COUNT(o.id) > 3
ORDER BY
  orders DESC
LIMIT
  10;

What changes from PostgreSQL to MySQL

  • Identifier quoting is rewritten from double-quoted "identifiers" to backtick `identifiers`.
  • Null-handling functions such as COALESCE() are mapped to IFNULL().
  • The result is re-indented and keyword-cased in MySQL style so it's ready to paste and run.

PostgreSQL to MySQL data type mapping

Query Studio translates queries, not schemas. When you come to move the tables themselves, this is what changes between PostgreSQL and MySQL:

Data type equivalents from PostgreSQL to MySQL
PostgreSQLMySQLWatch out for
SERIAL / GENERATED AS IDENTITYINT AUTO_INCREMENTMySQL allows one auto-increment column per table and it must be indexed.
BOOLEANTINYINT(1)MySQL accepts the BOOLEAN keyword but stores TINYINT(1). TRUE and FALSE become 1 and 0.
TEXTTEXT / LONGTEXTMySQL's TEXT caps at 64 KB. Anything that might exceed that needs MEDIUMTEXT or LONGTEXT.
TIMESTAMPTZDATETIME (store UTC)MySQL's TIMESTAMP has a range ending in 2038 and does time-zone conversion on read. Storing UTC in a DATETIME is the usual answer.
UUIDCHAR(36) or BINARY(16)MySQL has no UUID type. BINARY(16) with UUID_TO_BIN() is a quarter of the size and indexes far better.
JSONBJSONMySQL's JSON is already binary. Postgres's JSONB operators (@>, ?, #>) have no direct equivalent — they become JSON_CONTAINS and JSON_EXTRACT.
TEXT[] / any array typeJSON, or a join tableMySQL has no array types at all. This is a schema change, not a type change.
BYTEABLOB / LONGBLOBDirect equivalent.
NUMERIC without precisionDECIMAL(65,30)MySQL requires explicit precision; unconstrained NUMERIC has no equivalent.
INTERVALNo equivalent typeStore as seconds in an integer, or use MySQL's INTERVAL expression syntax inline.
CREATE TYPE … AS ENUMENUM('a','b') inline on the columnMySQL enums are per-column, not shared types.

PostgreSQL to MySQL: what actually catches people out

Syntax is the part a translator can fix. These are the differences that survive a clean conversion and show up later as wrong results rather than as errors.

You are giving up features, not just changing syntax

This direction loses real capability: array types, custom types, table inheritance, partial indexes, expression indexes, materialised views, window function support in older MySQL, DISTINCT ON, CTEs that MySQL 5.7 cannot parse, and transactional DDL. None of that is a syntax rewrite — every one of them is a design decision to make again. It is worth being sure the migration is genuinely necessary.

DISTINCT ON has no equivalent

Postgres's DISTINCT ON is the neatest way to get the latest row per group. MySQL needs a window function (8.0+) or a self-join against a grouped subquery. The rewrite is mechanical but never as short.

PostgreSQL
SELECT DISTINCT ON (user_id) *
FROM orders ORDER BY user_id, created_at DESC;
MySQL
SELECT * FROM (
  SELECT *, ROW_NUMBER() OVER (
    PARTITION BY user_id ORDER BY created_at DESC) rn
  FROM orders
) t WHERE rn = 1;

Arrays have to become a schema change

A TEXT[] column has no MySQL equivalent. The options are a JSON column, which cannot be indexed or joined the same way, or a proper join table, which is usually what the data wanted in the first place. Either way this is migration work that a query translator cannot do for you.

Transactional DDL goes away

In PostgreSQL you can wrap ALTER TABLE in a transaction and roll it back. MySQL commits implicitly on DDL. Migration tooling that relies on all-or-nothing schema changes needs rethinking before the move, not after a half-applied migration in production.

utf8 in MySQL is not UTF-8

MySQL's `utf8` is a three-byte subset that cannot store emoji or many CJK characters; the real thing is `utf8mb4`. Text arriving from PostgreSQL is genuine UTF-8, so the target columns and connection must be utf8mb4 or the import will truncate or error on the first four-byte character.

What this converter will not do

Query Studio translates SQL syntax. Being honest about the boundary is more useful than claiming there isn’t one — and on PostgreSQLMySQL specifically, these are the three that matter most:

Stored procedures, functions and triggers

Procedural code — PL/pgSQL, T-SQL procedures, MySQL routines — is a different language in every engine, with different control flow, error handling, variable declaration and transaction semantics. Query Studio translates queries, not programs. These have to be ported by hand.

Anything that depends on data rather than syntax

Whether a value fits the target type, whether a date is real, whether a text column's contents are valid UTF-8 — none of that is visible in the query. A translation can be syntactically perfect and still fail on the first row of the import.

Vendor-specific extensions

PostGIS geometry, MySQL spatial functions, SQL Server's FOR XML and hierarchyid, BigQuery's nested/repeated model, Snowflake's time travel. Where there is no equivalent concept, there is no translation — only a redesign.

The full list of what a syntax translator cannot do is on the Query Studio page.

How to convert PostgreSQL to MySQL

  1. Open the Query Studio editor and choose PostgreSQL as the “From” dialect.
  2. Choose MySQL as the “To” dialect.
  3. Paste your PostgreSQL query and press Translate — copy the MySQL result.

Try it with your own query

The editor is preloaded with PostgreSQLMySQL. You can also explain, format, validate and analyze the result.

Convert PostgreSQL to MySQL now →

Working with the data rather than the schema? Open a large CSV, JSON or Parquet file and query it with SQL — no upload, no row limit, and files far past what Excel will open.

PostgreSQL to MySQL FAQ

Is this PostgreSQL to MySQL converter free?

Yes — it's completely free with no account, no sign-up and no usage limits. Your query is processed to return the result and never stored.

Is the PostgreSQL to MySQL conversion accurate?

Query Studio rewrites syntax deterministically using real SQL parsers, so it gives the same result every time — there is no AI involved and no variation between runs. It handles the differences listed above automatically. What it cannot do is anything semantic: stored procedures, triggers, vendor extensions and performance characteristics all need a human. Review complex, vendor-specific queries before running them in production.

What breaks when migrating from PostgreSQL to MySQL?

The differences that most often cause problems on this pair: You are giving up features, not just changing syntax; DISTINCT ON has no equivalent; Arrays have to become a schema change; Transactional DDL goes away; utf8 in MySQL is not UTF-8. Each is explained in full above, with before-and-after examples where seeing it is quicker than reading about it.

How do PostgreSQL data types map to MySQL?

The full mapping table is above and covers 11 types. The ones that are not a straight rename: SERIAL / GENERATED AS IDENTITY → INT AUTO_INCREMENT, BOOLEAN → TINYINT(1), TEXT → TEXT / LONGTEXT, TIMESTAMPTZ → DATETIME (store UTC). Note that Query Studio translates queries rather than schemas — the table is there to tell you what your CREATE TABLE statements need, not to rewrite them for you.

Does this PostgreSQL to MySQL converter use AI?

No. Every result is computed by real SQL parsers and rule engines, which is what makes it free, instant, unlimited and identical on every run. Nothing is sent to a model, so there are no rate limits, no per-request cost to pass on, and no possibility of a confidently wrong answer that looks plausible.

Can I convert MySQL back to PostgreSQL?

Yes. Use the MySQL to PostgreSQL converter, or press the Swap (⇄) button inside the editor to flip the direction instantly. Note that a round trip is not guaranteed to return your original text — both directions normalise formatting, and where one dialect has no equivalent for a feature the information is genuinely lost rather than recoverable.

Other conversions

MySQL to PostgreSQLSQL Server to PostgreSQLPostgreSQL to SQL ServerMySQL to SQL ServerSQL Server to MySQLMySQL to Google BigQueryPostgreSQL to Snowflake