Welcome to Row by Row
Meet the new interactive SQL blog that turns every code block into a runnable DuckDB query.
You're reading a SQL tutorial. The author drops a query you want to try. What now? Open a terminal. Spin up DuckDB. Hope your version matches. Squint at the error.
Annoying. But DuckDB has a quiet trick — it compiles to WebAssembly, which means it can run in your browser.
dbquacks is a SQL learning game: pick a challenge, write a query, climb the leaderboard. Row by Row is where the same live editor publishes long-form tutorials and deep dives.
Try it
A tiny roster, already loaded.
CREATE OR REPLACE TABLE players(name, team, score, played_on) AS
SELECT * FROM (VALUES
('Eider', 'Mallards', 92, DATE '2026-04-01'),
('Duckbert', 'Mallards', 88, DATE '2026-04-01'),
('Pippin', 'Pintails', 79, DATE '2026-04-01'),
('Mira', 'Pintails', 95, DATE '2026-04-01')
) t(name, team, score, played_on);Hit Run on the query below.
SELECT name, team, score
FROM players
ORDER BY score DESC
LIMIT 3;Change LIMIT 3 to LIMIT 1 or swap DESC for ASC — worst case you get a SQL error, learn something, re-run.
The roster you just queried — Eider, Duckbert, Pippin, Mira, and the Mallards/Pintails league they play in — shows up across the SQL tutorials that follow.
What's coming
Three posts are already live: Two Ducks, One Database — a hands-on tour of Quack, DuckDB's HTTP client-server protocol; Shaping the Roster — GROUP BY ALL, SELECT * EXCLUDE, ORDER BY ALL, and the rest of DuckDB's friendlier SQL; and Looking Through the WINDOW — OVER, frames, and ranking.
After that, expect the corners DuckDB hides on purpose — recursive CTEs, ASOF joins, parquet straight from S3, and whatever else the language quietly does well.
All of it interactive. All of it fun. All of it ducks.
Atom feed at /blog/feed.xml.