Русское сообщество разработки на PHP-фреймворке Laravel.
Ты не вошёл. Вход тут.
Страницы 1
Привет, Всем.
как в поле timestamp найти определены промежуток но при этом игнорировать год.
надо выбрать сотрудников у которых день рождение было пять дней назад и пять дней вперед.
Не в сети
Если по промежутку времени нужно и без сырых запросов то так:
$startDate = Carbon::today()->subDays(5);
$endDate = Carbon::today()->addDays(5);
if ($startMonth === $endMonth) {
$users = User::whereMonth('created_at', $startDate->format('m'))
->whereDay('created_at', '>=', $startDate->format('d'))
->whereDay('created_at', '<=', $endDate->format('d'))
->get();
} else {
$users = User::where(function($q) use($startDate) {
$q->whereMonth('created_at', $startDate->format('m'))
->whereDay('created_at', '>=', $startDate->format('d'))
->whereDay('created_at', '<=', $startDate->copy()->endOfMonth()->format('d'));
})
->orWhere(function($q) use($endDate) {
$q->whereMonth('created_at', $endDate->format('m'))
->whereDay('created_at', '>=', $endDate->copy()->startOfMonth()->format('d'))
->whereDay('created_at', '<=', $endDate->format('d'));
})
->get();
}
Т.е. тебе нужно проверить в одном ли месяце находятся эти дни или нет. Логика для каждого случая своя.
Изменено AlexeyMezenin (03.03.2018 17:05:20)
Не в сети
Я поменял слегка.
$objUserNames = new User_name();
$date = Carbon::today();
$UserNames = User_name::whereMonth('birthday', '>', $date->subDays(5))
->whereDay('birthday', '>', $date->subDays(5))
->whereMonth('birthday', '<', $date->addDays(5))
->whereDay('birthday', '<', $date->addDays(5))
->get();
Но выборки нет.
а по чистому запросу в sql есть
SELECT * FROM `user_names` WHERE CONCAT( YEAR( NOW( ) ) , '-', DATE_FORMAT( `birthday` , '%m-%d %T' ) ) BETWEEN DATE_SUB( NOW( ) , INTERVAL 5 DAY ) AND DATE_ADD( NOW( ) , INTERVAL 5 DAY )
Можете подсказать где я ошибся?
Не в сети
Не в сети
Не надо менять код. Каждый вызов subDays(5) меняет переменную.
если не менять то вот : Call to undefined function App\Http\Controllers\today()!
Не в сети
Этот метод доступен начиная с 5.5. Если более ранняя версия, нужно заменить все четыре вызова на Carbon::today()
Не в сети
Ну я так и сделал. Не работает, выборки нет
$UserNames = $objUserNames::whereMonth('birthday', '>', Carbon::today()->subDays(5))
->whereDay('birthday', '>', Carbon::today()->subDays(5))
->whereMonth('birthday', '<', Carbon::today()->addDays(5))
->whereDay('birthday', '<', Carbon::today()->addDays(5))
->get();
dd($UserNames);
Не в сети
Carbon::today()->subDays(5)
я думаю что это не правильно. Результат этого кода будет дата на пять дней назад. Но главное что это будет полная дата. С годом, месяцем и временем.
date: 2018-02-24 00:00:00.0 UTC (+00:00)
}
Это не есть правильно. Выборку дней рождений надо сделать игнорируя год ...
Изменено macik (02.03.2018 00:08:56)
Не в сети
нет выборки. ;(
А как правильно прикрутить чистый SQL запрос в ларке? У меня не получается сделать запрос
SELECT * FROM `user_names` WHERE CONCAT( YEAR( NOW( ) ) , \'-\', DATE_FORMAT( `birthday` , \'%m-%d %T\' ) ) BETWEEN DATE_SUB( NOW( ) , INTERVAL 5 DAY ) AND DATE_ADD( NOW( ) , INTERVAL 5 DAY )
Это запрос работает на все 100%, но у меня не получается его правель прикрутить к своей модели ?!
Изменено macik (02.03.2018 10:50:53)
Не в сети
Я пробовал похожие запросы, все работает. Проверь логику запроса и данные, "поиграй" с ними, если вообще это нужно. Если тебе по-барабану сырой запрос использовать или Eloquent, тогда делай через сырые запросы
Не в сети
Я не могу понять. вроде делаю как надо
$UserNames = DB::select('SELECT * FROM `user_names` WHERE CONCAT( YEAR( NOW( ) ) , \'-\', DATE_FORMAT( `birthday` , \'%m-%d %T\' ) ) BETWEEN DATE_SUB( NOW( ) , INTERVAL 5 DAY ) AND DATE_ADD( NOW( ) , INTERVAL 5 DAY )');
Данных нет и все. Беру из dd() выдачи SQL запрос вставляю в phpmyadmin и все находит как надо?!
Что я делаю не так?
Не в сети
Получилось! Убрал экранирование и все заработало.
Не в сети
$UserNames = DB::select("SELECT * FROM `user_names` WHERE CONCAT( YEAR( NOW( ) ) , '-', DATE_FORMAT( `birthday` , '%m-%d %T')) BETWEEN DATE_SUB( NOW( ) , INTERVAL 5 DAY ) AND DATE_ADD( NOW( ) , INTERVAL 5 DAY )");
Ок.Сырой запрос работает.
А как можно его переделать в запрос с использованием метода и в слите Laravel?
Не в сети
@AlexeyMezenin, мне кажется ты упускаешь из виду особый случай, когда искомый интервал пересекает Новый Год. Чтобы этот кейс корректно разрулить, понадобится проверить ДВА промежутка МЕСЯЦ+ДЕНЬ через OR.
Я бы таки оставил дату рождения датой, но поправил её год на год начала искомого интервала, а потом использовал простой BETWEEN дата1 AND дата2
SELECT *
FROM persons
WHERE
(
birthday + INTERVAL YEAR(@start) - YEAR(birthday) YEAR
) BETWEEN @start AND (@start + INTERVAL 10 DAY)
http://sqlfiddle.com/#!9/a83133/3
Я использовал простой "+" для коррекции даты, так код чище, по моему. Старая версия MySQL может потребовать DATE_ADD().
Сконвертировать в цепочку Eloquent помоему несложно. Но сам проверять не буду понадобится ->whereRaw() а значит "девственность" eloquent потеряется.
Сделано по мотивам вот этого вопроса: https://stackoverflow.com/q/18747853/272885
Изменено artoodetoo (03.03.2018 16:32:28)
There are two hard things in computer science: cache invalidation, naming things, and off-by-one errors.
Не в сети
@AlexeyMezenin, мне кажется ты упускаешь из виду особый случай, когда искомый интервал пересекает Новый Год. Чтобы этот кейс корректно разрулить, понадобится проверить ДВА промежутка МЕСЯЦ+ДЕНЬ через OR.
Нет, я его тоже учитывал. От этого вообще не зависит, потому что год в запросе не учитывается вообще, это такой же случай, что и при датах в разных двух месяцах.
Но логика была неверная. Исправил для будущих читателей. Сложно вслепую такое писать, а задающий вопрос уже решил для себя использовать сырой запрос и не пытается поиграть с кодом на своих данных.
Не в сети
Извини, возможно я ошибся, т.к. говорил о прошлой редакции твоего сообщения
Сейчас это выглядит так: я прокоментировал вчера в 17:20 моего локального времени, а последняя редакция твоего сообщение вчера в 18:05.
Текущая редакция корректно справляется с границей месяца и года, если не считать мелких ляпов вроде — это будет полный перебор таблицы с прокачкой на сторону PHP для проверки, а значит будет тормозить даже на 10000 записей
Индусятина, но работает.
Пусть топикстартер выбирает вариант себе по душе.
There are two hard things in computer science: cache invalidation, naming things, and off-by-one errors.
Не в сети
Прошлая редакция тоже учитывала "Новый Год", но так логика неверная была в общем.
это будет полный перебор таблицы с прокачкой на сторону PHP для проверки. Индусятина, но работает.
Абсолютно нет. Этот код подготовит SQL запрос и вернет только нужные записи.
Не в сети
Кеш гугль хранит заведомо нерабочую редакцию, видимо я изначально комментировал её.
Приношу извинения за путаницу.
There are two hard things in computer science: cache invalidation, naming things, and off-by-one errors.
Не в сети
Абсолютно нет. Этот код подготовит SQL запрос и вернет только нужные записи.
я бы поспорил. есть негативный опыт с подобным запросом.
There are two hard things in computer science: cache invalidation, naming things, and off-by-one errors.
Не в сети
я бы поспорил. есть негативный опыт с подобным запросом.
Там два варианта запроса - выполняется только один из них. Первый - это абсолютно стандартный a AND b AND c. Второй - это стандартный (a AND b AND c) OR (d AND e AND f)
Не в сети
Окей, ты уже понял, да? Второй вариант с замыканиями потребует прокачки всех данных на PHP.
There are two hard things in computer science: cache invalidation, naming things, and off-by-one errors.
Не в сети
Второй вариант с замыканиями потребует прокачки всех данных на PHP.
Нет, не потребует. Вот первый запрос, генерируемый Eloquent
select * from `users` where month(`created_at`) = '02' and day(`created_at`) >= '12' and day(`created_at`) <= '22'
Вот второй запрос (более сложный):
select * from `users` where ((month(`created_at`) = '02' and day(`created_at`) >= '27' and day(`created_at`) <= '28') or (month(`created_at`) = '03' and day(`created_at`) >= '01' and day(`created_at`) <= '09'))
Не в сети
Ок, спасибо. Свой вариант мне по прежнему нравится больше.
There are two hard things in computer science: cache invalidation, naming things, and off-by-one errors.
Не в сети
Страницы 1