Ecto.Query.subquery

You're seeing just the function subquery, go back to Ecto.Query module for more information.
Link to this function

subquery(query, opts \\ [])

View Source

Converts a query into a subquery.

If a subquery is given, returns the subquery itself. If any other value is given, it is converted to a query via Ecto.Queryable and wrapped in the Ecto.SubQuery struct.

subquery is supported in from, join, and where, in the form p.x in subquery(q).

Examples

# Get the average salary of the top 10 highest salaries
query = from Employee, order_by: [desc: :salary], limit: 10
from e in subquery(query), select: avg(e.salary)

A prefix can be specified for a subquery, similar to standard repo operations:

query = from Employee, order_by: [desc: :salary], limit: 10
from e in subquery(query, prefix: "my_prefix"), select: avg(e.salary)

Subquery can also be used in a join expression.

UPDATE posts
  SET sync_started_at = $1
  WHERE id IN (
    SELECT id FROM posts
      WHERE synced = false AND (sync_started_at IS NULL OR sync_started_at < $1)
      LIMIT $2
  )

We can write it as a join expression:

set = from(p in Post,
  where: p.synced == false and
           (is_nil(p.sync_started_at) or p.sync_started_at < ^min_sync_started_at),
  limit: ^batch_size
)

Repo.update_all(
  from(p in Post, join: s in subquery(set), on: s.id == p.id),
  set: [sync_started_at: NaiveDateTime.utc_now()]
)

Or as a where condition:

subset = from(p in subset, select: p.id)
Repo.update_all(
  from(p in Post, where: p.id in subquery(subset)),
  set: [sync_started_at: NaiveDateTime.utc_now()]
)

If you need to refer to a parent binding which is not known when writing the subquery, you can use parent_as as shown in the examples under "Named bindings" in this module doc.