@kirill-93

Laravel toSql в DB::raw?

Здравствуйте, подскажите, как я могу вставить sql запрос, полученный через toSql() в DB::raw?
Понадобилось перенести такой запрос на Eloquent:
#
SELECT * FROM a
LEFT JOIN (
    SELECT * FROM b WHERE ...
) AS Q2 ON Q2.id = a.id


В Eloquent, на сколько я понял нельзя использовать селект внутри джоина.
В гугле советуют внутрь JOIN'а вставлять DB::raw
#
DB::table('users') ->select('first_name', 'TotalCatches.*')
->join(DB::raw('(SELECT ...) TotalCatches'), function($join) {
    $join->on('users.id', '=', 'TotalCatches.user_id');
})
->orderBy('TotalCatches.CatchesPerDay', 'DESC')
->get();


Это действительно работает, и я сделал так:
- Внутренний запрос получил через toSql()
$sql = Model::where(...)->toSql();
Затем этот sql вставил в join

#
Entity::leftJoin(\DB::raw('(' . $sql . ') AS LJ'), function($join) {
                $join->on('entities.id', '=', \DB::raw('LJ.entity_id'));
            })
            ->selectRaw('...');


В результате скрипт ругается, потому что в итоге в $sql попал запрос с "?" вместо значений.

#
select ... 
from `bq_entities` 
left join (
    select * 
    from `bq_posts` 
    where `entity_id` in (?) and `id` not in (?)
) AS LJ on `bq_entities`.`id` = LJ.entity_id

То есть нужно в DB::raw подставить действительно "сырой" запрос, а не сгенерированный через toSql(), но мне нужно именно через toSql(), потому что я использую scope для внутреннего запроса.
Что можно сделать?
  • Вопрос задан
  • 3437 просмотров
Решения вопроса 1
Denormalization
@Denormalization
Если же отвечать по теме вопроса, то можно сделать такой костыль:
$builder = Model::where('....');
$sql = $builder->toSql();
$bindings = $builder->getBindings();
foreach ($bindings as $binding) {
  $value = is_numeric($binding) ? $binding : "'".$binding."'";
  $sql = preg_replace('/\?/', $value, $sql, 1);
}

echo $sql;


Но оно как-то попахивает :)
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы