SQL Query Visualizer
See a SQL SELECT, UPDATE or DELETE statement as a tree — the query as the root, every clause branching off it to the right — instead of formatted text.
SQL query (SELECT, UPDATE or DELETE)
Formatted query
Query tree diagram
How the query tree diagram works
This tool runs a hand-written recursive-descent parser over your SQL — it doesn't reformat text like a pretty-printer, it builds a real abstract syntax tree (AST) and lays that tree out ROOTED AT THE QUERY ITSELF, growing left to right. The statement's head node — SELECT's column list, UPDATE's SET, DELETE's marker — is the root, drawn at the far left; every clause is a direct child branching off it to the right, the same way a dendrogram or an org chart branches, just rotated 90° so it grows sideways instead of downward:
-- Before (flat SQL text)
SELECT id FROM orders
WHERE (status = 'active' OR status = 'pending')
AND created_at > '2024-01-01'
-- After (a tree, root at the left, branching right)
SELECT (root)
+- FROM orders
+- WHERE
+- AND
+- OR ┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
| +- status='active' ┊
| +- status='pending' ┊ (dashed: explicit parens)
| ┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
+- created_at > '2024-01-01'
The dashed outline around the OR branch is exactly what the parentheses in your query meant: without them, a OR b AND c would parse as a OR (b AND c) instead, because AND binds tighter than OR in every SQL dialect — the diagram makes that precedence visible instead of leaving it to be inferred from the text. UPDATE and DELETE follow the same model: their target table(s) and WHERE clause branch off the root exactly the same way, ending in a SET or DELETE root instead of a SELECT projection.
Frequently asked questions
What SQL does this tool support?
SELECT, UPDATE and DELETE statements: for SELECT, the column list (including *, table.*, aliases, arithmetic and function calls like COUNT(id)), FROM with multiple comma-joined tables, INNER/LEFT/RIGHT/FULL/CROSS JOIN chains with their ON conditions, WHERE and HAVING with full AND/OR/NOT grouping, GROUP BY, ORDER BY, LIMIT/OFFSET/TOP, and subqueries in FROM, in WHERE (IN or EXISTS) or as a column value. UPDATE (SET, optional FROM, WHERE) and DELETE (optional USING, WHERE) use the same tree model. CREATE, INSERT and other DDL are intentionally out of scope: a schema (ER) diagram is a different kind of visualization problem, not a smaller version of this tool, so that input shows a clear, specific message instead of a wrong diagram. CTEs (WITH), UNION and window functions aren't parsed yet either.
Why is SELECT (or SET / DELETE) drawn as the root, not FROM?
The diagram is a rooted tree, not a flowchart: the statement's head node — SELECT's projection, UPDATE's SET, DELETE's marker — sits at the far left as the root, and every clause (sources, WHERE/HAVING and their AND/OR sub-trees, GROUP BY, ORDER BY, LIMIT) is a direct child branching off it to the right, the same way a dendrogram or an org chart branches — just rotated so it grows rightward instead of downward. That's a deliberate choice: it reads as "this is the query, and these are its parts" rather than as a left-to-right data flow.
How does the diagram show AND vs OR logic?
WHERE, HAVING and each JOIN's ON condition are drawn as a compact box that itself branches further right into its own AND/OR condition tree: AND and OR each get their own connector node, and explicit parentheses around a group are drawn as a dashed outline around that whole sub-tree — so (a OR b) AND c visibly shows the OR grouped separately from the outer AND.
How are subqueries shown?
A subquery is parsed with the same parser, recursively, and rendered as its own nested tree — its own root, its own branches — inside a distinctly dashed, boxed-in panel, clearly subordinate to the FROM, WHERE or column it belongs to, however deep the nesting goes.
Does the dialect selector fully support MySQL, PostgreSQL and SQL Server?
No — it's honestly scoped to the one structural difference that actually changes parsing: row-limiting syntax. Generic/ANSI and PostgreSQL use LIMIT n OFFSET m, MySQL uses the same LIMIT/OFFSET, and SQL Server uses TOP n (right after SELECT) or OFFSET m ROWS FETCH NEXT n ROWS ONLY. Identifier quoting ("double", `backtick`, [bracket]) is accepted leniently in every dialect. Proprietary functions, data types and other engine-specific syntax aren't modeled.
Is my SQL sent anywhere?
No. Formatting, parsing and rendering all happen entirely in your browser with plain JavaScript; nothing is ever uploaded to a server.