Я работаю с Laravel Eloquent, чтобы получать записи из таблицы views
, фильтруя их по определенным датам video_ids
и created_at
. Мне также нужно присоединиться к другой таблице devices
, чтобы применить дополнительные фильтры на основе типов устройств, регионов и имен хостов.
Вот структура моих таблиц:
views
таблица:
devices
таблица:
И вот структура моего запроса:
// this is an example of what $dates looks like
// $dates = ['2024-08-01', '2024-08-02', '2024-08-03'];
public function getViews($videoIds, $dates, $devices, $regions, $sources){
// Filter by video_id and created_at first
$query = View::whereIn('views.video_id', $videoIds)
->whereIn(DB::raw('DATE(views.created_at)'), $dates);
// Apply the join and other filters only if devices, regions, or sources are provided
if (!empty($devices) || !empty($regions) || !empty($sources)) {
$query->join('devices', 'devices.id', '=', 'views.device_id');
$query->when(!empty($devices), function ($query) use ($devices) {
return $query->whereIn('devices.types', array_map(fn($device) => $device['value'], $devices));
});
$query->when(!empty($regions), function ($query) use ($regions) {
return $query->whereIn('devices.country', array_map(fn($region) => $region['value'], $regions));
});
$query->when(!empty($sources), function ($query) use ($sources) {
return $query->whereIn('new_devices.hostname', array_map(fn($source) => $source['value'], $sources));
});
}
return $query->get();
}
Проблема, с которой я столкнулся, заключается в том, что после применения соединения набор результатов включает представления с датами create_at, которых нет в предоставленном мной массиве $dates
. Мне нужно, чтобы запрос возвращал только записи, дата которых находится в указанном диапазоне, даже после применения соединения.
Мой вопрос:
Я ищу решение, которое гарантирует, что набор результатов включает только представления с датами create_at в предоставленном массиве $dates, даже если через соединение применяются дополнительные фильтры.
Любая помощь будет принята с благодарностью!
🤔 А знаете ли вы, что...
PHP можно использовать для работы с XML-документами.
При выполнении join
запросов всегда SELECT
используйте нужные вам столбцы. Предположим, у вас есть следующие данные (пропуская ненужные столбцы)
просмотры
устройства
Если вы выполняете запрос типа
SELECT * from views join devices on devices.id = views.device_id;
Сервер базы данных вернет строку типа
Обратите внимание, что здесь есть два created_at
: views.created_at
и devices.created_at
.
Когда это читается PHP, он преобразует его в объект/массив, и они не могут иметь повторяющихся ключей, он использует только последний дублирующийся ключ. Таким образом, он будет использовать второй массив среди следующих
['id' => 1, 'device_id' => 1, 'created_at' => '2024-01-01T00:00:00'] // This is what you expected
['id' => 1, 'device_id' => 1, 'created_at' => '2024-08-02T00:00:00'] // This is what you got
Скорее всего, это тот сценарий, с которым вы столкнулись: created_at
, который вы видите в своих результатах, скорее всего, из другой таблицы.
Чтобы решить эту проблему, вы можете указать, из какой таблицы вы хотите выбрать столбцы, используя функцию выбора.
View::select('views.*', 'devices.created_at as device_created_at', /* other columns you need from devices */)