Does DynamoDB support SQL?
Partly. DynamoDB supports PartiQL, a SQL-compatible query language for SELECT, INSERT, UPDATE, and DELETE statements. It is not full SQL: there are no JOINs, no GROUP BY, and no arbitrary aggregations, and efficient queries still require targeting the primary key or an index. If you want those missing pieces, DynoTable's SQL Workbench runs real JOIN, GROUP BY, and aggregate queries over your DynamoDB tables from the desktop.
What PartiQL gives you
A familiar SQL syntax for the four data operations. You can write SELECT * FROM "Orders" WHERE ... instead of constructing low-level API calls, which is convenient and readable.
What it does not give you
- No JOINs — DynamoDB is nonrelational; you denormalize instead.
- No GROUP BY / aggregates — grouping and summing happen in your application.
- No free-form scans for cheap — a
SELECTwithout a key condition still runs a Scan and costs accordingly.
Where the parser stops
These are not features you can reach with different syntax. Run them and the statement never gets as far as reading an item:
SELECT "region", SUM("total") FROM "Orders" GROUP BY "region"
ValidationException: Unsupported clause: GROUP BY
SELECT COUNT(*) FROM "Orders"
ValidationException: Unexpected path component at 1:8:5
SELECT SUM("total") FROM "Orders"
ValidationException: Unexpected path component at 1:8:3
SELECT DISTINCT "region" FROM "Orders"
ValidationException: Unsupported token in expression: DISTINCTLook at what the aggregate errors say. There is no aggregate function for the parser to turn down, so COUNT(*) is read as an attribute path and falls over on the *, at column 8. That is how thin the SQL surface is.
ORDER BY is the one to know about, because it looks like it works:
SELECT * FROM "Orders" WHERE "pk" = 'U#1' ORDER BY "total"
ValidationException: Variable reference total in ORDER BY clause must be part of the primary keyYou can sort by the sort key, ascending or descending, and by nothing else. Sorting by any other attribute is your application's job, after the read.
The mental model
Think of PartiQL as a syntax layer over DynamoDB's existing Query, Scan, and write operations; the same access-pattern rules apply underneath.
Real SQL (JOIN, GROUP BY, aggregates) with DynoTable
PartiQL stops at single-table SELECT. DynoTable's SQL Workbench goes further: it runs actual JOIN, GROUP BY, and aggregate functions (COUNT, SUM, AVG, MIN, MAX) over your DynamoDB tables. It reads the items through the normal DynamoDB API, then executes the relational part of the query in the client: SQL within DynamoDB's access-pattern rules, since each join still reads through a real key or index. So the three things PartiQL can't do, you write as one statement:
SELECT c.region, COUNT(*) AS orders, SUM(o.total) AS revenue
FROM Orders o
JOIN Customers c ON o.customerId = c.id
GROUP BY c.regionIt stays honest about the underlying constraints (an unbounded join is an unbounded read), so the fastest queries are the ones whose join or WHERE hits a partition key or index. Full detail in SQL for DynamoDB and the product manual at /docs/dynamodb-sql-workbench.
Prototype the PartiQL side of the same data model with the
DynamoDB query builder — it emits partition-scoped
Query programs that stay on the efficient path PartiQL SELECT uses when a key
condition is present.
Go deeper
Compare the two in PartiQL vs SQL, see PartiQL examples, and read SQL for DynamoDB. Download DynoTable to write PartiQL, and real JOIN, GROUP BY, and aggregates, against your tables.
References
- PartiQL - a SQL-compatible query language for Amazon DynamoDB — Amazon DynamoDB Developer Guide
- PartiQL select statements for DynamoDB — Amazon DynamoDB Developer Guide
- Query data in DynamoDB (SQL to NoSQL) — Amazon DynamoDB Developer Guide
Last verified 2026-07-13 against the official AWS documentation linked above.
Every ValidationException above was reproduced 2026-07-28 against DynamoDB Local 3.3.0 via @aws-sdk/client-dynamodb 3.1095.0 and is quoted verbatim, column offsets included.