Как рассчитать дату и время в Laravel Eloquent на основе минут динамического столбца

Я пытаюсь выполнить запрос на основе двух баз данных и столбцов.

$model->where('response_time', '<=', Carbon::now()->subMinutes(\DB::raw('anotherTable.created_at'))->diffInMinutes(Carbon::now()))

response_time содержит целое число минут, например: 15

Если anotherTable.created_at - response_time (т. е. менее 15 минут) меньше текущего времени, верните строку.

Я пробовал это выше, но мне не повезло, и я не знаю, как отлаживать мой запрос. Любая помощь приветствуется.

Пример запроса, который должен пройти и вернуть свою строку (через 1 минуту):

response_time 15

anotherTable.created_at 21-03-2022 13:40:00

Текущее время: 21-03-2022 13:56:00

Вы не можете использовать столбец в Carbon для использования в запросе. Вам повезет больше, используя DB::raw с DATE_SUB

aynber 21.03.2022 14:52

Спасибо @aynber что-то вроде $model->raw('DATE_SUB(anotherTable.created_at, response_time) <= NOW()') ? - Вроде тоже не работает, но выглядит правильно

Jaquarh 21.03.2022 14:56

вам придется либо выполнить запрос в 2 этапа, либо использовать подзапросы

Dev Man 29.03.2022 21:49
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
1
3
196
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Попробуйте это :)

$model->where('response_time', '<=', Carbon::now()
    ->diffInMinutes(\DB::raw('anotherTable.created_at')));

Поскольку Carbon находится только в PHP, у него не будет доступа к значению anotherTable.created_at из базы данных во время создания запроса. Вместо этого Carbon выполнит и вернет значение до того, как запрос будет отправлен в базу данных.

Will B. 03.04.2022 09:20

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

Вместо этого вы должны делать свои расчеты по базе данных.

Приведенный ниже код теоретически должен работать, хотя я его не проверял.

Все расчеты, требующие данных базы данных, выполняются в базе данных.

Углерод используется только для передачи ему значения условия.

$model->where(
    DB::raw('DATE_SUB(anotherTable.created_at, INTERVAL response_time MINUTE)'), '<=', Carbon::now()
);

Я надеюсь, что это поможет вам

Carbon::parse('21-03-2022 13:40:00')->diffInMinutes(new DateTime)

Или

Carbon::parse('21-03-2022 13:40:00')->diffInMinutes(Carbon::now())

в вашем случае используйте это:

Carbon::parse(DB::raw('anotherTable.created_at'))->diffInMinutes(Carbon::now())

Поскольку Carbon находится только в PHP, у него не будет доступа к значению anotherTable.created_at из базы данных во время создания запроса. Вместо этого Carbon выполнит и вернет значение до того, как запрос будет отправлен в базу данных.

Will B. 03.04.2022 09:23
Ответ принят как подходящий

Почему Карбон не работает

Carbon не может получить значение из базы данных во время генерации запроса на стороне PHP ($model->where()). Carbon вместо этого будет выполняться немедленно для string значения 'anotherTable.created_at' перед отправкой запроса в базу данных. Эквивалент:

$offset = Carbon::now()
    ->subMinutes('anotherTable.created_at')
    ->diffInMinutes(Carbon::now()); // 0 

$model->where('response_time', '<=', $offset); // WHERE responst_time <= 0

Разбивка углеродного процесса

Carbon\Traits\Date::__call() используется для анализа действия и единиц из имени метода как sub и minutes.
Процесс условно вызывает Carbon\Traits\Units::subUnit('minute', 'anotherTable.created_at')[sic], который вызывает Carbon\Traits\Units::addUnit($unit, -$value, $overflow)[sic].

-$value в конечном итоге обрабатывается PHP как -'anotherTable.created_at', что приводит к 0, как если бы вы вызвали Carbon::now()->subMinutes(0).

На проблему было бы указано, если бы Carbon вызывал исключение TypeError при предоставлении string для аргумента $value, в отличие от ожидаемого int. Однако аргумент $value в Carbon\Traits\Units::subUnit($unit, $value) не является типизированным.


Разрешение MySQL

Вместо использования Carbon используйте функцию MySQL TIMESTAMPDIFF(), чтобы получить разницу в минутах между anotherTable.created_at и NOW() в запросе.

db<>рабочий пример Пример

При условии, что anotherTable добавляется с JOIN в запросе.

$model->where(
    'response_time', '<=',  DB::raw('TIMESTAMPDIFF(MINUTE, anotherTable.created_at, NOW())')
);

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