PartiQL: first queries
The front door of the dialect series: read items out of one table and choose what comes back. Two statements in, you'll also know how to read the "Executes as" strip — the habit that makes the whole dialect legible.
- Run your first
SELECTagainst a base table and a GSI - Project and alias columns, and de-duplicate results with
DISTINCT - Build computed columns from expressions, scalar functions, and
SELECT VALUE - Read the "Executes as" strip to see the exact native request before you run
Your first SELECT
SELECT * FROM "stage.Users" -- base tableSELECT * FROM "stage.Users"."ByOrg" -- a GSI FROM "table"reads the base table;FROM "table"."index"reads a GSI. Quote names — especially namespaced ones containing dots ("stage.Users").- Keywords read case-blind everywhere; attribute names are case-sensitive on the wire (native re-emissions use your schema's canonical casing).
That's already a real query. Without a WHERE clause it reads the whole table — fine for a small dev stage, and exactly the thing Targeted reads teaches you to avoid on a big one.
Projection: choose your columns
SELECT Name AS n, Age FROM "stage.Users" -- projection + aliasSELECT DISTINCT Country FROM "stage.Users" -- de-duplicated SELECT *or an attribute list.ASaliases are lowered — DynamoDB has noAS, so sources project natively and rename client-side per fetched item. Top-level attributes only;ORDER BYmay reference the alias.FROMaliases (FROM "stage.Users" AS x WHERE x.pk = …) are likewise lowered: the alias strips andx.-qualified paths re-spell bare before the wire. ExplicitASonly; paths inside string literals are never rewritten.DISTINCTde-duplicates each fetched page client-side with deep value equality — numbers by value, sets order-insensitive. Duplicates across page boundaries can reappear.
How aliases are lowered
AS. The studio projects the native attribute names and renames each fetched item client-side — so SELECT Name AS n ships as a projection of Name, with the rename applied after the wire. FROM aliases behave the same way: x.pk re-spells to a bare pk before the request leaves. Every client-side step is disclosed in the "Executes as" strip. *Because it all happens after the read, client-side shaping — aliases, computed columns, DISTINCT — changes what you see, never what DynamoDB reads or bills.* What controls the bill is the WHERE clause — covered in Targeted reads.Computed columns: expressions & functions
-- expressions in the SELECT listSELECT Name, balance * 1.1 AS adjusted, address.city, Name || ' <' || email || '>' AS contactFROM "stage.Users" WHERE pk = 'User#9'-- SELECT VALUE: each row IS the valueSELECT VALUE {'who': Name, 'next': balance + 1} FROM "stage.Users" A projected column can be an expression, not just an attribute: document paths (address.city, tags[0]), arithmetic, || concatenation, comparisons, and tuple/array constructors. The native read projects just the root attributes the expressions touch; each row is then shaped client-side, so a column whose value comes out MISSING is simply omitted from that row.
A library of scalar functions rides the same grammar — string (upper, substring), numeric (abs, mod), null-handling (coalesce), date/time (year, to_epoch / from_epoch, date_add), and regex (regex_like) — each evaluated per fetched row. SELECT VALUE projects each row as the evaluated value rather than a named-column tuple. The keyword reference lists every function with a one-line example; these are all lowered — computed client-side and disclosed in the strip.
Relabel with CASE
CASE expression maps a stored value to a label without leaving the query — CASE Status WHEN 1 THEN 'Pending' WHEN 2 THEN 'Shipped' ELSE Status END AS status. Both forms work: simple (CASE attr WHEN value …) and searched (CASE WHEN condition …). It's a SELECT-list expression like any other, evaluated per fetched row; an unmatched row with no ELSE makes that column MISSING and omitted. One rule worth knowing early: CASE in a normal read WHERE is refused — WHERE decides the Query/Scan plan, so it can't be a client-side fold. Full entry in the keyword reference.Read the "Executes as" strip
Every statement you type is analysed at the keystroke. The "Executes as" strip shows the exact native DynamoDB request the statement translates to, live, with one-click copy — and the editor colours intent before you run: key conditions tint green, a predicate that degrades to a full-table Scan flags amber with the table's live item count, and anything that won't run is squiggled with the reason.
Make checking the strip a reflex now, while the statements are one-liners. Once joins, subqueries, and aggregates enter the picture, single statements compile to multiple native requests — the strip is how you always know what's about to ship.
Flip between the two variants above: the same projection, but dropping the WHERE turns a 1-RCU Query into a 12,480-item Scan — the strip and the footer tell the story before you ever pay for it. Both samples are editable and copyable; live execution against your own tables happens in DynoStudio.
- PartiQL for DynamoDB AWS docs: native PartiQL syntax and DynamoDB's supported statement family.
- Core components of Amazon DynamoDB AWS docs: tables, items, attributes, primary keys, and secondary indexes.
FROM "table"reads a base table;FROM "table"."index"reads a GSI — always quote namespaced names.- Projection picks columns;
ASandFROMaliases are lowered (renamed client-side);DISTINCTde-duplicates per page. - Projected columns can be expressions and scalar functions;
SELECT VALUEprojects each row as its evaluated value. - The "Executes as" strip is your ground truth — check it on every statement.
SELECT Name AS n do its renaming?SELECT with no WHERE clause compiles to…Name (renamed to who) alongside their balance from stage.Users.AS natively — the studio lowers it. You still write it the SQL way.Show solution
AS alias is lowered: Name is projected natively and renamed client-side per item.SELECT Name AS who, balance FROM "stage.Users" Country values across the table.DISTINCT de-duplicates each fetched page client-side — duplicates can reappear across page boundaries.Show solution
DISTINCT runs client-side with deep value equality.SELECT DISTINCT Country FROM "stage.Users" contact column shaped like Ada <ada@x.com>, combining Name and email.Show solution
||. The native read projects just the root attributes the expression touches (Name, email); the string is assembled client-side.SELECT Name || ' <' || email || '>' AS contactFROM "stage.Users" WHERE pk = 'User#9'