У меня начинаются головные боли из-за этого, поэтому я решил просто опубликовать это здесьУ меня есть две таблицы, которые связаны через сводную таблицу (так как это отношение многие ко многим).Я использую Laravel и Eloquent (но общая помощь в том, как этого добиться с помощью обычных запросов SQL, также высоко ценится).
Я хочу заказать первую таблицу на основе столбца второй, но столбец должен быть «агрегирован»за это.
Пример с автомобилями, которые используются многими водителями и могут иметь разные цвета:
Car-Table: [id, color]
Driver-Table: [id, name]
Car.Driver-Table: [car_id, driver_id]
Мне нужен запрос, который получает все драйверы, которые только ездят на красных автомобилях итогда все, что не водит красные машины.
Мне нужно использовать запрос, потому что я, возможно, впоследствии сделаю другие вещи (например, фильтрацию) с этим запросом и в конце хочу разбить на страницы.
Я уже использую запросы, которые получают одну из двух групп.Они выглядят так: В модели драйвера:
public function redCars() {
return $this->cars()->where('color', 'red');
}
public function otherColoredCars() {
return $this->cars()->where('color', '<>', 'red');
}
А затем где-то в контроллере:
$driversWithOnlyRedCars = Driver::whereDoesntHave('otherColoredCars')->get();
$driversWithoutRedCars = Driver::whereDoesntHave('redCars')->get();
Есть ли способ объединить эти два?
Может быть, яЯ просто думаю, что здесь неправильно.
Обновление для уточнения:
В принципе мне нужно что-то подобное (или любым другим способом, который приведет к тому же результату)
$driversWithOnlyRedCars->addTemporaryColumn('order_column', 0); // Create temporary column with value 0
$driversWithoutRedCars->addTemporaryColumn('order_column', 1);
$combinedQuery = $driversWithOnlyRedCars->combineWith($driversWithoutRedCars); // Somehow combine both queries
$orderedQuery = $combinedQuery->orderBy('order_colum');
$results = $combinedQuery->get();
Обновление 2
Думаю, я узнал, как приблизиться к своей цели с помощью необработанных запросов.
Было бы что-то вроде этого:
$a = DB::table(DB::raw("(
SELECT id, 0 as ordering
FROM drivers
WHERE EXISTS (
SELECT * FROM cars
LEFT JOIN driver_car ON car.id = driver_car.car_id
WHERE driver.id = driver_car.driver_id
AND cars.color = 'red'
)
) as only_red_cars"));
$b = DB::table(DB::raw("(
SELECT id, 1 as ordering
FROM drivers
WHERE EXISTS (
SELECT * FROM cars
LEFT JOIN driver_car ON car.id = driver_car.car_id
WHERE driver.id = driver_car.driver_id
AND cars.color <> 'red'
)
) as no_red_cars"));
$orderedQuery = $a->union($b)->orderBy('ordering');
Теперь проблема в том, что мне нужномодели, заказанные таким образом, и в итоге разбиты на страницы, так что это не совсем ответ на мой вопрос.Я пытался преобразовать это обратно в модели, но мне пока не удалось.Что я пробовал:
$queriedIds = array_column($orderedQuery->get()->toArray(), 'id');
$orderedModels = Driver::orderByRaw('(FIND_IN_SET(drivers.id, "' . implode(',', $queriedIds) . '"))');
Но похоже, что FIND_IN_SET
допускает только столбец таблицы в качестве второго параметра.Есть ли другой способ получить модели в правильном порядке из запроса упорядоченного объединения?