НАИМЕНЬШЕЕ и БОЛЬШОЕ значение даты из нескольких таблиц, способ laravel

Есть ли какой-нибудь "Laravel-ish" способ зафиксировать самые ранние и самые поздние даты из нескольких полей даты в нескольких таблицах laravel?

таблица для модели1:

fielda| fieldb| date1

таблица2 для модели2:

fieldc| fieldd| date1| date2

Я не мог найти никакого элегантного способа сделать это. Мой текущий подход выглядит примерно так:

$model1_dates = Model1::select(\DB::raw('MIN(date1) as min_date'), \DB::raw('MAX(date1) as max_date'))->get(); $model2_dates = Model2::select(\DB::raw('MIN(date2) as min_date'), \DB::raw('MAX(date2) as max_date'))->get(); $model2_dates2 = Model2::select(\DB::raw('MIN(date2) as min_date'), \DB::raw('MAX(date1) as max_date'))->get();

после этого я сравню результаты и получу минимум и максимум из них...

Какие подходы были бы лучше?

В случае производительности я бы предложил добиться этого на стороне MySQL. Выберите из своих таблиц, упорядочите по *, получите первый результат и последний результат.

Tarasovych 23.05.2019 14:39

Итак, для этого нет никакого подхода "Laravel"...

Angelin Calu 23.05.2019 14:45

Моя первая попытка была примерно такой: `$earliest model 1 = Model 1::order By('idate1', 'asc')->pluck('date1')->first();`, но это будет означать еще одну шаг к сравнению

Angelin Calu 23.05.2019 14:46
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
В предыдущем посте мы создали функциональность вставки и чтения для нашей динамической СУБД. В этом посте мы собираемся реализовать функции обновления...
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
Роли и разрешения пользователей без пакета Laravel 9
Роли и разрешения пользователей без пакета Laravel 9
Этот пост изначально был опубликован на techsolutionstuff.com .
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
1
3
769
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Да, есть такие функции, как max() и min(). Также вы можете объединить два запроса с помощью метода union()Агрегированные методыСоюз

И вы также можете использовать orderBy с laravel. Работает также на даты. Сортировать по

Самый быстрый способ:

$minDateModel1 = Model1::min('date1');
$maxDateModel1 = Model1::max('date1');

Или:

$minDateModel1 = Model1::oldest('date1')->first()->pluck('date1');
$maxDateModel1 = Model1::latest('date1')->first()->pluck('date1');

Или:

$minDateModel1 = Model1::max('date1');

//should be the oldest first, newest at last
$minDateModel1 = Model1::orderBy('date1', 'asc')->first()->pluck('date1');
$maxDateModel1 = Model1::orderBy('date1', 'asc')->first()->pluck('date1');

Должен сделать трюк:

$minDateModel1 = Model1::max('date1');
$minDateModel21 = Model2::max('date1');
$minDateModel22 = Model2::max('date2'); 
$allMinDates = $allMinDates->merge($minDateModel1);
$allMinDates = $allMinDates->merge($minDateModel21);
$allMinDates = $allMinDates->merge($minDateModel22);
$min = $allMinDates->min();

Как я прокомментировал ветку комментариев к вопросам, OrderBy был моим первым подходом.

Angelin Calu 23.05.2019 14:51

Отредактировал ответ. Надеюсь, вам понравится, и вы оставите несколько голосов.

liqSTAR 23.05.2019 15:21

Я немного упростил код для ясности, на самом деле у меня есть как минимум 5 полей даты в 3 разных таблицах. @PaulSpiegel, не могли бы вы опубликовать ответ о том, как должен выглядеть SQL-запрос? Будет ли это хорошим случаем для использования оператора CASE sql?

Angelin Calu 23.05.2019 15:28

Прошил ларавельский способ, ни разу не было сказано, что это быстрее или лучше sql. Он также может запустить необработанный sql-запрос внутри laravel. Он также может определить функции, которые найдут для него минимум и максимум и просто вызовут их в запросе.

liqSTAR 23.05.2019 15:35

@AngelinCalu Но необработанный запрос не похож на Laravel.

Paul Spiegel 23.05.2019 15:41

@liqSTAR Я просто хочу убедиться, что для вас «laravel-ish» — это что-то вроде «аккуратный код любой ценой — производительность не имеет значения».

Paul Spiegel 23.05.2019 15:43

Теперь я понимаю, что подход «ларавела» не подходит для моего текущего случая. Думал, что это может быть какой-то вспомогательный метод, который мне может не хватать. Если необработанный запрос - это путь, я выберу этот маршрут :)

Angelin Calu 23.05.2019 15:46

В laravel простой способ - это один запрос для каждого столбца, который я хочу найти, мин/макс. Затем мне нужно снова проверить результаты. В SQL вы должны присоединиться к таблице и выполнить НАИМЕНЬШЕЕ или БОЛЬШЕЕ минимальное/максимальное значение каждого столбца. Но вы также проверяете каждую колонку. Еще три запроса в одном запросе. Что касается целочисленных операций, которые необходимо выполнить, я бы сказал, что это тот же объем работы. Независимо от того, что мы предпочитаем... ответ на вопрос.

liqSTAR 23.05.2019 15:48

Любые рекомендуемые подходы к необработанному запросу?

Angelin Calu 23.05.2019 15:50

Обычный выбор, присоединение к любой таблице с датами, затем указание имен столбцов каждой таблицы в функции НАИМЕНЬШИЙ. LEAST(min(t1.date1),min(t2.date2),min(t2.date2),...)

liqSTAR 23.05.2019 15:54

«Что касается целочисленных операций, которые необходимо выполнить, я бы сказал, что это тот же объем работы» - речь идет вовсе не о количестве «операций». Речь идет о задержке. Не стоит недооценивать коммуникационные издержки SQL-запроса даже в локальной базе данных. 6 запросов против 1 может быть не так уж и много. Но когда у вас есть 20 таблиц и около 50 полей с датами, мне будет не все равно.

Paul Spiegel 23.05.2019 16:19
Ответ принят как подходящий

Я использовал Laravel, но я не фанат - поэтому я действительно не знаю, что такое Laravel-ish или что это такое. Если вы имеете в виду "что-то, что выглядит просто", то это может быть

$minDate = collect([
    Model1::min('date1'),
    Model2::min('date1'),
    Model2::min('date2'),
])->min();

$maxDate = collect([
    Model1::max('date1'),
    Model2::max('date1'),
    Model2::max('date2'),
])->max();

Это аккуратно - но это 6 запросов к БД.

Один необработанный SQL будет

select min(min_date) as min_date, max(max_date) as max_date
from (
    select min(date1) as min_date, max(date1) as max_date from table1
    union all
    select min(date1) as min_date, max(date1) as max_date from table2
    union all
    select min(date2) as min_date, max(date2) as max_date from table2
) x

или

select min(min_date) as min_date, max(max_date) as max_date
from (
    select min(date1) as min_date, max(date1) as max_date
    from table1
    union all
    select min(least(date1, date2))    as min_date,
           max(greatest(date1, date2)) as max_date
    from table2
) x

в зависимости от того, какие у вас индексы. Первый запрос работает лучше, когда у каждого столбца даты есть свой индекс.

Мне нравится твой ответ. Честно и довольно прямолинейно. Это то, что я мог придумать. Не могли бы вы помочь мне проверить производительность этого решения по сравнению с вашим? sqlfiddle.com/#!9/caa5e3/7

Angelin Calu 23.05.2019 16:05
FROM table1, table2 это перекрестное соединение - хуже вряд ли получится :)
Paul Spiegel 23.05.2019 16:08

Другие вопросы по теме