Skip to main content

VillageSQL is a drop-in replacement for MySQL with extensions.

All examples on this page work on VillageSQL. Install Now →
A subquery in WHERE supplies a value. A subquery in FROM supplies a whole table, which the outer query then reads as if it were real. That is a derived table, and it is how you query the result of a query. Open the client with mysql -u root -p sakila before you start.

How a derived table works

Replace COLUMN_LIST with the columns you want, TABLE_NAME with the table the inner query reads, and ALIAS_NAME with a name for the result. The inner query’s column names, including any aliases, become the derived table’s columns. The server builds the inner result first, then runs the outer query over it.

What it makes possible

A GROUP BY replaces the detail rows with 1 row per group, so a grouped query cannot show you the rows themselves. A derived table keeps both: group in the inner query, then join the result back to the detail. This lists films longer than the average for their own rating, and shows that average beside each one.
Neither WHERE nor HAVING can write this on its own. HAVING filters groups and would have thrown the titles away; WHERE runs before any average exists. The 5 averages are worked out once in the inner query, and the join attaches the right one to every film. The Correlated subqueries lesson answers the same question a row at a time. This shape computes the averages once instead.

The alias is not optional

ERROR 1248 always means this, and the fix is always the same: put AS SOME_NAME after the closing bracket. The name can be anything, and it is worth making it describe the rows, because a reader meets it before they read the query that produced it.

Derived table or CTE

A common table expression does the same job with the subquery lifted out to the top and given a name. The 2 forms produce the same rows, and the next lesson covers the difference. When a MySQL CTE beats a derived table measures which one the optimizer treats differently.

Summary

  • Use a derived table to query the result of a query.
  • Give it an alias, because ERROR 1248 is what you get without one.
  • Expect the inner query’s column aliases to become the derived table’s columns.
  • Reach for it when you need to filter or join on a computed column.
  • Prefer a CTE once the query has several stages or repeats the same subquery.

See also