SQL Query Builder

Build a SELECT with joins and get JDBC or Python code for it.

Runs in your browser Free · no account

Loading the query builder…

About the SQL Query Builder converter

Writing data access code by hand is repetitive in a way that invites mistakes: the column list in the SQL, the parameter indexes on the statement, the fields on the result class and the reads from the result set all have to agree, and nothing checks that they do until something is wrong at runtime.

Add your columns and joins here and all four fall out of one description of the query, so they cannot drift apart.

As many columns and joins as the query needs

Add columns one at a time, each with an optional alias and the SQL type it really has. Add joins the same way — inner, left, right or full — with the alias and the ON condition you would write yourself.

Everything is composed rather than parsed, so there is no query dialect to trip over and no risk of the tool quietly misreading a query and generating code for a different one.

Outer joins produce nullable types

A column from a LEFT or FULL joined table has no row at all when the join finds no match. The generated Java boxes those columns and reads them with getObject, so a missing row arrives as null rather than as a silent zero from getInt.

Python gets the same treatment: those fields are typed Optional, so a type checker will make you handle the case rather than letting it surface in production.

Java: a prepared statement and a record

The Java output is a small final class holding the SQL as a text block, a record describing one row, and a static fetch method taking a Connection plus one argument per filter. Statements and result sets are opened in try-with-resources, so nothing leaks if a read throws.

Imports are emitted for exactly the types used. It compiles as-is on Java 17 or later against any JDBC driver.

Python: a dataclass and psycopg

The Python output is a frozen dataclass for the row, the SQL as a module-level constant, and a function that runs the query with a cursor and returns a list of rows.

Parameters use the %s placeholder that psycopg and most other DB-API drivers expect, passed as a tuple so the driver does the escaping.

Frequently asked questions

Is the generated code safe from SQL injection?

Yes. Every value you filter on becomes a bound parameter — a ? in the JDBC statement or a %s in the Python one — and is passed to the driver separately from the query text. Nothing is concatenated into the SQL, which is the only reliable way to be safe.

Which SQL dialects does it produce?

Plain ANSI SELECT syntax, which runs unchanged on PostgreSQL, MySQL, SQLite, MariaDB and H2. LIMIT is the one clause that varies — SQL Server and older Oracle want TOP or FETCH FIRST instead.

Can it read an existing query and convert it?

No, and that is deliberate. A parser that mostly understands SQL would occasionally misread a query and generate confident, wrong code. Composing the query from parts means the output always matches what you described.

Why does it ask for the type of each column?

Because SQL text alone does not say what a column holds, and the generated code needs a real type for the result class and the right accessor to read it. Picking the type once is what makes the output compile rather than needing edits.

Does it support subqueries, unions or window functions?

Not as structured fields, but a column or condition is free text, so an expression such as COUNT(*) OVER (PARTITION BY u.id) works — give it an alias and a type and it is generated like any other column.

Does my schema get uploaded anywhere?

No. The builder runs entirely in your browser. Table and column names never leave the page, which matters because a schema is often the most sensitive thing about an internal service.