# `Selecto.Builder.Subselect`

SQL generation logic for Subselect functionality.

This module handles the construction of correlated subqueries that return
aggregated data from related tables as JSON arrays, PostgreSQL arrays,
or other aggregate formats.

# `build_correlated_subquery`

```elixir
@spec build_correlated_subquery(Selecto.Types.t(), Selecto.Types.subselect_selector()) ::
  {Selecto.Types.iodata_with_markers(), Selecto.Types.sql_params()}
```

Build the correlated subquery that fetches related data.

# `build_correlated_subquery`

```elixir
@spec build_correlated_subquery(
  Selecto.Types.t(),
  Selecto.Types.subselect_selector(),
  String.t()
) ::
  {Selecto.Types.iodata_with_markers(), Selecto.Types.sql_params()}
```

# `build_single_subselect`

```elixir
@spec build_single_subselect(Selecto.Types.t(), Selecto.Types.subselect_selector()) ::
  {Selecto.Types.iodata_with_markers(), Selecto.Types.sql_params()}
```

Build a single correlated subquery for a subselect configuration.

# `build_single_subselect`

```elixir
@spec build_single_subselect(
  Selecto.Types.t(),
  Selecto.Types.subselect_selector(),
  String.t()
) ::
  {Selecto.Types.iodata_with_markers(), Selecto.Types.sql_params()}
```

# `build_subselect_clauses`

```elixir
@spec build_subselect_clauses(Selecto.Types.t()) ::
  {[Selecto.Types.iodata_with_markers()], Selecto.Types.sql_params()}
```

Build subselect clauses for the SELECT portion of the query.

Returns a list of SQL fragments that can be included in the main SELECT clause.
Each subselect becomes a correlated subquery that aggregates related data.

# `build_subselect_clauses`

```elixir
@spec build_subselect_clauses(Selecto.Types.t(), String.t()) ::
  {[Selecto.Types.iodata_with_markers()], Selecto.Types.sql_params()}
```

# `resolve_join_condition`

```elixir
@spec resolve_join_condition(Selecto.Types.t(), atom()) ::
  {:ok, {String.t(), String.t()}} | {:error, String.t()}
```

Resolve the join condition needed to correlate the subquery with the main query.

# `resolve_join_condition_with_path`

```elixir
@spec resolve_join_condition_with_path(Selecto.Types.t(), atom()) ::
  {:ok, Selecto.Types.iodata_with_markers()} | {:error, String.t()}
```

# `resolve_join_condition_with_path`

```elixir
@spec resolve_join_condition_with_path(Selecto.Types.t(), atom(), String.t()) ::
  {:ok, Selecto.Types.iodata_with_markers()} | {:error, String.t()}
```

# `resolve_join_condition_with_path`

```elixir
@spec resolve_join_condition_with_path(
  Selecto.Types.t(),
  atom(),
  String.t(),
  [atom()] | nil
) ::
  {:ok, Selecto.Types.iodata_with_markers()} | {:error, String.t()}
```

# `wrap_in_aggregation`

```elixir
@spec wrap_in_aggregation(
  Selecto.Types.iodata_with_markers(),
  Selecto.Types.sql_params(),
  Selecto.Types.subselect_format(),
  Selecto.Types.subselect_selector()
) :: {Selecto.Types.iodata_with_markers(), Selecto.Types.sql_params()}
```

Wrap subquery results in the appropriate aggregation function.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
