framework/db/ActiveQuery.php
public function joinWith($with, $eagerLoading = true, $joinType = 'LEFT JOIN')
    {
        $relations = [];
        foreach ((array) $with as $name => $callback) {
            if (is_int($name)) {
                $name = $callback;
                $callback = null;
            }

            if (preg_match('/^(.*?)(?:\s+AS\s+|\s+)(\w+)$/i', $name, $matches)) {
                // relation is defined with an alias, adjust callback to apply alias
                list(, $relation, $alias) = $matches;
                $name = $relation;
                $callback = function ($query) use ($callback, $alias) {
                    /* @var $query ActiveQuery */
                    $query->alias($alias);
                    if ($callback !== null) {
                        call_user_func($callback, $query);
                    }
                };
            }

            if ($callback === null) {
                $relations[] = $name;
            } else {
                $relations[$name] = $callback;
            }
        }
        $this->joinWith[] = [$relations, $eagerLoading, $joinType];
        return $this;
    }
public function joinWith($with, $eagerLoading = true, $joinType = 'LEFT JOIN')
    {
        $relations = [];
        foreach ((array) $with as $name => $callback) {
            if (is_int($name)) {
                $name = $callback;
                $callback = null;
            }

            if (preg_match('/^(.*?)(?:\s+AS\s+|\s+)(\w+)$/i', $name, $matches)) {
                // relation is defined with an alias, adjust callback to apply alias
                list(, $relation, $alias) = $matches;
                $name = $relation;
                $callback = function ($query) use ($callback, $alias) {
                    /* @var $query ActiveQuery */
                    $query->alias($alias);
                    if ($callback !== null) {
                        call_user_func($callback, $query);
                    }
                };
            }

            if ($callback === null) {
                $relations[] = $name;
            } else {
                $relations[$name] = $callback;
            }
        }
        $this->joinWith[] = [$relations, $eagerLoading, $joinType];
        return $this;
    }
Joins with the specified relations.

This method allows you to reuse existing relation definitions to perform JOIN queries.
Based on the definition of the specified relation(s), the method will append one or multiple
JOIN statements to the current query.

If the `$eagerLoading` parameter is true, the method will also perform eager loading for the specified relations,
which is equivalent to calling [[with()]] using the specified relations.

Note that because a JOIN query will be performed, you are responsible to disambiguate column names.

This method differs from [[with()]] in that it will build up and execute a JOIN SQL statement
for the primary table. And when `$eagerLoading` is true, it will call [[with()]] in addition with the specified relations.

@param string|array $with the relations to be joined. This can either be a string, representing a relation name or
an array with the following semantics:

- Each array element represents a single relation.
- You may specify the relation name as the array key and provide an anonymous functions that
can be used to modify the relation queries on-the-fly as the array value.
- If a relation query does not need modification, you may use the relation name as the array value.

The relation name may optionally contain an alias for the relation table (e.g. `books b`).

Sub-relations can also be specified, see [[with()]] for the syntax.

In the following you find some examples:

```php
// find all orders that contain books, and eager loading "books"
Order::find()->joinWith('books', true, 'INNER JOIN')->all();
// find all orders, eager loading "books", and sort the orders and books by the book names.
Order::find()->joinWith([
'books' => function (\yii\db\ActiveQuery $query) {
$query->orderBy('item.name');
}
])->all();
// find all orders that contain books of the category 'Science fiction', using the alias "b" for the books table
Order::find()->joinWith(['books b'], true, 'INNER JOIN')->where(['b.category' => 'Science fiction'])->all();
```

The alias syntax is available since version 2.0.7.

@param bool|array $eagerLoading whether to eager load the relations
specified in `$with`.  When this is a boolean, it applies to all
relations specified in `$with`. Use an array to explicitly list which
relations in `$with` need to be eagerly loaded.  Note, that this does
not mean, that the relations are populated from the query result. An
extra query will still be performed to bring in the related data.
Defaults to `true`.
@param string|array $joinType the join type of the relations specified in `$with`.
When this is a string, it applies to all relations specified in `$with`. Use an array
in the format of `relationName => joinType` to specify different join types for different relations.
@return $this the query object itself