Всем привет! В этом посте хотел поведать о возможностях написания запросов при помощи query builder в laravel.
В нете много информации о разных вариантах использования данной настройки, я же опишу то, что не нашел решая определенную проблему с запросом.
Мне было необходимо использовать несколько уровней вложенных запросов, при этом используя один из них в качестве временной таблицы. Исходные данные: таблица партнеров partners, таблица расписания работы партнеров partners_calendar, таблица филиалов партнеров filials, таблица услуг партнеров partners_services. Требовалось получить список партнеров у которых есть расписание на требуемый период времени по определенной услуге партнера с выводом филиалов в которых они работают в данном периоде. Вот как составлен запрос:
$partners = DB::table(DB::raw("partners as p, filials as f, (select distinct dc.org_id, dc.partner_id from partners_calendar dc where dc.partner_id in
(select d.id from partners d left join partners_services ds on ds.partner_id = d.id where ds.subservice_id = $subservice_id)) as sq where d.id = sq.partner_id and f.id_suborg = sq.org_id"))
->select(DB::raw('d.*, f.name as suborgname, f.id_suborg'))->get();
В query builder имеются возможности создания вложенных запрос при помощи join и встроенной в него functions() в которой описывается сам подзапрос, но в моей ситуации это не помогало. Поэтому используется функционал DB::raw, который позволяет передавать параметры binding в запрос (переменная $subservice_id, которая хранит id определенной услуги) а также хитро формировать сам запрос используя возможности laravel. Как видно я использую DB:raw в определении таблиц DB::table, где делаю сам подзапрос создания временной таблицы sq, использую binding, а также добавляю условия where в «определение таблиц»!! В select получаю необходимые поля в склеенном необходимом мне виде также через DB::raw.
Добавление условий where в определение таблиц на первый взгляд кажется ересью с точки зрения нормального написания запросов на языке sql для MySQL. Но учитывая преобразования laravel query builder’a именно такая конструкция формируется в правильный sql запрос который пойдет к базе (посмотреть запрос можно добавив вместо get() toSql().
Вот такая небольшая статья о тонкостях работы с query builder. Используемая версия laravel — 5.5.