Developer Tools

SQL Query Generator

Choose a task, fill in your table and column names, and get SQL written for your database. The generator knows the differences between MySQL, PostgreSQL, SQLite and SQL Server, uses placeholders for values, and explains the choices it made. Nothing is executed.

  • Private by default
  • No sign-up
  • Free to use

Comma-separated. Leave empty for all columns (*) when reading.

One per line as name: type. Types: id, string, text, integer, decimal, boolean, date, datetime, json. Add ! for NOT NULL.

Condition (WHERE)

Leave the column empty for no condition. For IN, separate values with commas.

Comma-separated, in the same order as the columns. Used only when placeholders are off.

Leave empty for no limit.

Output

    This tool only writes SQL text. Nothing is executed and no database is contacted.

    How to use SQL Query Generator

    1. Choose what you want to do: read, change or define data.
    2. Select your database and enter the table and column names.
    3. Fill in the fields for the task, such as the condition, sort order or join keys.
    4. Read the notes under the result, then copy or download the SQL.

    SQL Query Generator features

    Fifteen everyday tasks

    Filtering, searching, date ranges, pagination, grouping, joins, duplicates, latest row per group, insert, upsert, update, delete, tables, columns and indexes.

    Four dialects

    LIMIT or OFFSET … FETCH, ON CONFLICT or ON DUPLICATE KEY or MERGE, identifier quoting and column types follow the selected database.

    Prepared-statement placeholders

    Values become ?, $1 or @p1 with the parameters listed below the query.

    Guard rails

    UPDATE and DELETE without a condition are refused until you confirm, and = NULL is caught.

    Explanations

    Each query comes with notes on why it is written that way and what to watch for.

    Text only

    The SQL is generated in your browser. No database connection, no execution.

    When to use SQL Query Generator

    • Writing a query in a dialect you use rarely.
    • Getting pagination, date ranges or upserts right without looking up the syntax.
    • Finding and cleaning up duplicate rows.
    • Drafting CREATE TABLE and index statements for a new feature.

    SQL Query Generator FAQ

    How is this different from the SQL Query Builder?

    The generator starts from a task, such as “find duplicates” or “latest row per group”, and produces a complete, idiomatic statement for it. The builder lets you assemble a SELECT clause by clause. Use the generator when you know what you want but not how to write it.

    Why are there question marks instead of my values?

    They are placeholders for a prepared statement. Your code sends the query and the values separately, and the database never interprets a value as SQL. This is the standard protection against SQL injection. Untick the option to see literal values instead.

    Why does the date range use < the next day?

    If the column stores a time as well as a date, BETWEEN '2026-01-01' AND '2026-01-31' stops at midnight at the start of the 31st and misses that whole day. “Greater than or equal to the first day, and less than the day after the last” is correct for both date and timestamp columns.

    Are table and column names checked against my database?

    No. The tool has no connection to any database. It writes the names as you enter them, quoting them when they contain special characters or are reserved words. Typos will surface when you run the query.

    Is the generated SQL safe to run on production?

    Read queries are harmless. For UPDATE and DELETE, first run a SELECT with the same WHERE clause to see which rows are affected, and make sure you have a backup. The notes below each query repeat this advice where it applies.

    What does the upsert do on each database?

    It inserts a row, or updates the existing one when the key already exists. MySQL uses INSERT … ON DUPLICATE KEY UPDATE, PostgreSQL and SQLite use INSERT … ON CONFLICT … DO UPDATE, and SQL Server uses MERGE. All require a unique index or primary key on the key column.

    The same question in four dialects

    SQL is standardised, and every database implements the standard a little differently. The core of a query, SELECT, FROM, WHERE, GROUP BY and ORDER BY, is portable. The differences show up at the edges that everyday work touches constantly. Limiting rows is LIMIT in MySQL, PostgreSQL and SQLite, and OFFSET … FETCH or TOP in SQL Server. Identifier quoting uses backticks, double quotes or square brackets. An auto-incrementing key is declared four different ways. A generator that knows these details saves a lookup each time.

    Some tasks have a well-known correct form that is easy to get slightly wrong. Pagination must be sorted by something unique, or rows can appear on two pages. A date range should be half-open so that the last day is fully included. The “latest row per group” problem is solved cleanly with the ROW_NUMBER window function, where older approaches with a self-join or a correlated subquery are slower and harder to read. Duplicates are found with GROUP BY and HAVING. The generator writes these established forms and says why.

    The most important habit it encourages is separating code from data. A query assembled by gluing user input into a string is the cause of SQL injection, still one of the most common serious vulnerabilities. With placeholders, the statement has a fixed shape and the values travel separately, so nothing a user types can change what the query does. Every modern database driver supports this, and the generated parameter list shows the order in which to pass the values.

    Statements that change data deserve extra care, which is why UPDATE and DELETE without a condition are not produced by accident here. In practice, preview the affected rows with a SELECT, run the change inside a transaction where your database supports it, and check the reported row count before committing. For structure changes, remember that adding an index or a column to a large table can lock it for a while; test on a copy first.

    Other useful tools