CTE stands for Common Table Expressions in SQL. They are temporary result sets defined within a single query using the WITH clause, acting like named subqueries to improve readability and structure.
I was morbidly curious what a "good CTE" could possibly be...
Seems to be this:
> Chronic traumatic encephalopathy (CTE) is a progressive neurodegenerative disease […]
> Evidence indicates that repetitive concussive and subconcussive blows to the head cause CTE. In particular, it is associated with contact sports such as boxing, American football, Australian rules football, wrestling, mixed martial arts, ice hockey, rugby, and association football.
https://en.wikipedia.org/wiki/Chronic_traumatic_encephalopat...
edit: syntax. voice to text was liberal with the comma abuse
It'd be quite surprising the WITH statement in top a query to be the first feature to learn/use past basic SQL. Is it personal experience in some industry?
Sure, yes, OP should (and now has) defined the term. But at the same time it's reasonable to expect that someone reading a blog post on BoringSQL.com would already know the term just as much as we could expect people interested in Clojure would know what a REPL is.
This is a valuable comment, don't ruin it with sarcasm and rudeness.
no it wouldn't
the whole point is to critique the post
> Use the term, never define the term, classic.
Communicate the same thing in a way you'd do to someone's face:
> This article doesn't define the term "CTE".
Or even more directly, still not rude:
> I wish the article had defined its terms! "CTE" stands for "Common Table Expressions..."
These days I often write queries like this (especially when doing exploratory ad hoc queries, but also in apps) even when it's not necessary to use a CTE:
WITH
a AS (
SELECT ... FROM ... WHERE ... etc.
)
SELECT * FROM a
The first CTE query defines the input, and the main query just reads from it. Subsequent subqueries invoke steps on that input to group, filter, join, and so on.This has a bunch of nice benefits. For example, it allows me to add steps incrementally, and to "comment out" a step I can simply change the next step's input to read from the preceding step. Each step can be read and understood in isolation.
I work a lot with Postgres, ClickHouse, and SQLite, and generally find that the database inlines and optimizes CTEs, and challenges mostly concern performance traps (like IN or EXISTS) that allly to non-CTE situations as well.
Regarding recursive CTEs, you might be interested in how DuckDb evolved them with USING KEY: https://duckdb.org/2025/05/23/using-key
If you want something that is more like actual recursion (I.e., depth-first), Oracle has CONNECT BY which does not require the same kind of tracking. It also comes with extra features to help with cycle detection, stack depth reflection, etc.
If your problem is aligned with the DFS model, the oracle technique can run circles around recursive CTEs. Anything with a deep hierarchy and early termination conditions is a compelling candidate.
All that is supported with CTEs as well. And both Postgres and Oracle support the SQL standard for these things.
You can't choose between breadth first/depth first using CONNECT BY in Oracle. Oracle's manual even states that CTE are more powerful than CONNECT BY
Obviously makes only sense for stuff like analytical queries that are not running constantly.
I just rewrote all queries with claude code and next day and compute decreased to 1/5th.
Embarassingly, despite thinking of myself as pretty knowledgeable with SQL, I had no idea you could nest DML statements inside a CTE. I always assumed/used DML statements as the final statement after a CTE was defined. I'm not sure if or when I might use this in the future, but it's neat to learn something new (and to be humbled at the same time).
I'll write some nice clean CTEs and then have to refactor it to temp tables due to the lack of materialization.