laravel, добавление sql в конструктор запроса, left join с условием

Имеется некоторый запрос. В него внесена модификация, суть которой в том, чтобы произошел left join на основе 2х полей, но второе поле использовалось только если оно не NULL. На sql эта часть запросы выглядит так:

left join `stores_remains`  on 
IF(`products`.`color_id` IS NULL, 
`stores_remains`.`parent_id` = IFNULL(products.parent_id, products.id) ,
`stores_remains`.`parent_id` = IFNULL(products.parent_id, products.id) 
              AND `stores_remains`.`color_id` = `products`.`color_id`)

В конструкторе запроса я попробовал такой вариант:

$query->leftJoin('stores_remains', function ($join) {
   $join->on(DB::raw("IF(`products`.`color_id` IS NULL, 
    `stores_remains`.`parent_id` = IFNULL(products.parent_id, products.id) ,
    `stores_remains`.`parent_id` = IFNULL(products.parent_id, products.id) 
     AND`stores_remains`.`color_id` = `products`.`color_id`)"));
                }); 

Но в $join->on() нужно указывать 3 параметра, из-за этого в запросе автоматически добавлялось = `` , что вызывало ошибку. Вопрос в том как правильно вписать данный запрос в конструктор запроса laravel?


Ответы (1 шт):

Автор решения: Waldemar

Изначально, цель задачи была в том, что бы сделать сортировку по полю total_remains , но из-за null в color_id часть записей некорректно джойнилось в итоге в total_remains у некоторых записей так же был null (что не соответствует действительности).

Свою задачу я решил следующим образом:

$query->leftJoin('stores_remains', function ($join) {
        $join->on('stores_remains.parent_id', '=', DB::raw('IFNULL(products.parent_id, products.id)'));
        $join->on('stores_remains.color_id', '=', 'products.color_id')
              ->whereNotNull('products.color_id');
                            });
$query->leftJoin(DB::raw('stores_remains AS t2'), function ($join) {
       $join->on('t2.parent_id', '=', DB::raw('IFNULL(products.parent_id, products.id)'))
             ->whereNull('products.color_id');
                            });

т.е. 2 раза left join одной и той же таблицы для полей с null и без.

Сортировку же сделал так:

$query->orderByRaw("COALESCE(stores_remains.total_remains, t2.total_remains) DESC");
→ Ссылка