Как в laravel в качестве таблицы указать таблицу созданную динамически подзапросом

Рейтинг: 0Ответов: 1Опубликовано: 19.04.2023

в документации по ларавель не могу найти пример подзапроса для создания таблицы для выборки, делаю так

    $res1 = DB::table(function($q) {
        return DB::table('current_table')
            ->select(DB::raw('count(first_input) as cuntd, date(first_input) as dated'))
            ->whereBetween('first_input', ['2020-01-01 00:00:00', '2023-05-01 00:00:00'])
            ->groupBy(DB::raw("date(first_input)"))
            ->orderBy('dated', 'ASC')->get();
    })
    ->select('*')
    ->get();

в итоге ошибка Object of class Closure could not be converted to string помогите пожалуйста решить проблему)

Ответы

▲ 0Принят

В документации по DB::table я не нашел, что должна возвращать анонимная функция, которая передана как параметр.

Но если посмотреть сорцы, становится понятно, что в анонимной функции нужно через билдер определить подзапрос, причем ничего возвращать не требуется. Вот этот код:

/**
 * Makes "from" fetch from a subquery.
 */
public function fromSub($query, $as)
{
    [$query, $bindings] = $this->createSub($query);

    return $this->fromRaw('('.$query.') as '.$this->grammar->wrapTable($as), $bindings);
}

protected function createSub($query)
{
    // If the given query is a Closure, we will execute it while passing in a new
    // query instance to the Closure. This will give the developer a chance to
    // format and work with the query before we cast it to a raw SQL string.
    if ($query instanceof Closure) {
        $callback = $query;

        $callback($query = $this->forSubQuery());
    }

    return $this->parseSub($query);
}

Я специально оставил комментарий - он проливает свет.

Затем я попробовал сделать на своей таблице и поправил названия таблицы и столбцов. Остальное оставил как есть. Получилось так:

$res1 = DB::table(function (\Illuminate\Database\Query\Builder $q) {
    $q
        ->from('sessions')
        ->selectRaw('count(*) as cuntd, date(created_at) as dated')
        ->whereBetween('created_at', ['2020-01-01 00:00:00', '2023-05-01 00:00:00'])
        ->groupBy(DB::raw('date(created_at)'))
        ->orderBy('dated', 'ASC');
})
    ->select('*')
    ->get();

Это работает. В анонимной функции нужно определить через билдер запросов подзапрос.