Build a SELECT statement without typing it: choose a table, add joins (the ON condition is filled in from your foreign keys), pick columns and aggregates, add WHERE and HAVING filters, sort and limit. The tool writes clean, formatted SQL for MySQL, PostgreSQL, SQLite or SQL Server and explains anything that would fail.
Last updated:
Your tables
FROM
SELECT columns
WHERE (filter rows)
GROUP BY & HAVING
ORDER BY & LIMIT
Your SQL
Advertisement
Advertisement
How to use the SQL Query Builder
Check your tables: open Your tables and paste CREATE TABLE statements, or keep the sample online-store schema.
Pick the FROM table and add joins. The tool suggests a related table and fills in the ON columns from foreign keys; adjust them if needed.
Choose the columns to return, with an optional function such as COUNT or SUM and an alias.
Add filters: WHERE conditions filter rows, HAVING conditions filter groups after aggregation.
Sort and limit, choose your database, then copy or download the SQL.
Anatomy of a SELECT query
The sample query built on load answers a real question: which customers in the US and Canada placed at least two orders, and how much did they spend?
Clause
In the example
Purpose
SELECT
c.id, c.full_name, COUNT(o.id) AS order_count, SUM(o.total) AS total_spent
Columns and calculated values to return
FROM / JOIN
customers AS c LEFT JOIN orders AS o ON o.customer_id = c.id
Where the rows come from and how tables match
WHERE
c.country IN ('US', 'CA')
Filter individual rows
GROUP BY
c.id, c.full_name
One output row per customer
HAVING
COUNT(o.id) >= 2
Filter groups using aggregates
ORDER BY
total_spent DESC
Sort the result, here by an alias
LIMIT
LIMIT 10
Return only the first rows
Join types
Join
Returns
Typical use
INNER JOIN
Only rows matched in both tables
Orders with their customer
LEFT JOIN
All left rows, NULLs where the right side has no match
All customers, including those with no orders
RIGHT JOIN
All right rows, NULLs where the left side has no match
Rarely needed; swap the tables and use LEFT JOIN
FULL JOIN
All rows from both sides
Reconciling two lists (not available in MySQL)
CROSS JOIN
Every combination of rows
Generating a calendar × product grid
Tips for correct, fast queries
Filter a LEFT-joined table in the ON clause, not in WHERE: WHERE o.status = 'paid' removes customers without orders and silently turns the LEFT JOIN into an INNER JOIN.
COUNT(column) skips NULLs while COUNT(*) counts rows, so with a LEFT JOIN use COUNT(o.id) to get 0 for customers without orders.
Always ORDER BY when paging with LIMIT / OFFSET, otherwise rows can move between pages.
Index the columns used in JOIN … ON and WHERE, especially foreign keys like orders.customer_id.
Use parameters in application code (WHERE email = ?) instead of pasting user input into SQL.
Frequently asked questions
In what order does SQL run the clauses?
Logically a SELECT is evaluated as FROM and JOIN, then WHERE, GROUP BY, HAVING, SELECT, DISTINCT, ORDER BY and finally LIMIT / OFFSET. That is why WHERE cannot use aggregates or column aliases, HAVING can use aggregates, and ORDER BY can use the aliases from SELECT.
What is the difference between WHERE and HAVING?
WHERE filters individual rows before they are grouped, so it cannot use functions like COUNT or SUM. HAVING filters the groups after GROUP BY, for example HAVING COUNT(o.id) >= 2 to keep only customers with at least two orders.
What is the difference between INNER JOIN and LEFT JOIN?
INNER JOIN returns only rows that have a match in both tables. LEFT JOIN returns every row of the left table and fills the right table's columns with NULL where there is no match, so customers without orders still appear with a count of 0.
Why does every non-aggregated column have to be in GROUP BY?
When rows are grouped, each output row stands for many input rows, so a plain column must have one value per group. Standard SQL requires it to be in GROUP BY (PostgreSQL allows columns that depend on a grouped primary key, and MySQL's ONLY_FULL_GROUP_BY mode enforces the rule). The builder adds them automatically.
How is LIMIT written in SQL Server?
SQL Server has no LIMIT. The builder uses SELECT TOP (n) for a plain limit, and ORDER BY … OFFSET n ROWS FETCH NEXT m ROWS ONLY when you also skip rows. OFFSET requires an ORDER BY clause.
How are values in filters quoted?
Numbers compared with numeric columns stay unquoted, other values become string literals with single quotes doubled for safety. IN lists are split on commas. Values like :name, ?, $1 or @param are kept as parameter placeholders, which is what you should use in application code to avoid SQL injection.
Does the builder run the query?
No. It only writes the SQL text in your browser. Run it in your database client, or try it on a CSV file with the Query CSV with SQL tool.
Are all the tools on FreeToolCabin tested for quality and accuracy?
Yes! Every tool on our site undergoes automated Q/A testing in real browser environments to ensure high precision, correct output, and zero errors. If you happen to spot a bug or have a suggestion, please contact us at [email protected] and our team will review it right away.