Найти клиентов, у которых есть дни рождения в следующие 7 дней в laravel - PullRequest
2 голосов
/ 20 июня 2019

Мне нужно получить список клиентов, у которых есть дни рождения в ближайшие 7 дней в laravel.Я использовал следующий запрос.этот запрос также прошел дни рождения.

 $customerslist=Customers::WhereRaw('DAYOFYEAR(curdate()) <= DAYOFYEAR(date_of_birth) AND DAYOFYEAR(curdate()) + 7 >=  dayofyear(date_of_birth)' )->OrderBy(DB::raw("DAYOFYEAR(date_of_birth)"),'ASC')->get();

Я использую приведенный ниже запрос, перечисленный ниже, но пропускаю некоторых клиентов enter image description here

Отсутствует клиент

enter image description here

Ответы [ 6 ]

2 голосов
/ 20 июня 2019

для немедленного решения я создал необработанный запрос

// start range 7 days ago
$start = date('z') + 1 - 7;
// end range 7 days from now
$end = date('z') + 1 + 7;
$customerslist = Customers::whereRaw("DAYOFYEAR(birthday) BETWEEN $start AND $end")->get();

EDITED

Итак, я создал 5000 записей сслучайный год и дата

MethodOne Использование Eloquent filter

$checkRange =   array_map(
        function ($date) {
            return $date->format('Y-m-d');
        },
        \Carbon\CarbonPeriod::create(now(), now()->addDays(7))->toArray()
    );


    $carbonWay = Customer::get()->filter(function($eachCus) use ( $checkRange){
        return in_array( $eachCus->dob, $checkRange);
    });

Но если у вас Много клиентов , это приведет к перегреву сервера sql

Метод Два QueryBuilder Way

 $eloquentway = Customer::whereDate('dob','>=', now())
                    ->whereDate( 'dob', '<=', now()->addDays(7))
                    ->get();

Так что оба результата одинаковы для меня одинаково

Наконец я проверил, есть ли идентификаторытакие же матчи

$idsofCarbon = $carbonWay->pluck('id')->toArray();
    $idsofFilter = $elequentway->pluck('id')->toArray();

    dump(array_diff( $idsofFilter, $idsofCarbon));
    dump(array_diff( $idsofCarbon, $idsofFilter));

Оба дают мне [] Что означает, что результат точен

Подробнее о фильтрации даты

https://laraveldaily.com/eloquent-date-filtering-wheredate-and-other-methods/https://laravel.com/docs/5.8/queries#where-clauses

Просьба прокомментировать, если возникнут проблемы

Надеюсь, это поможет

1 голос
/ 22 июня 2019

Как отмечает @TimLewis в комментариях, ваша модель имеет поле date-of-birth, и вы используете его для сравнения с текущей датой (вероятно, через много лет после даты рождения).

php решение:

для удобства чтения и для решения проблем с переворачиванием года, вы должны:

  1. использовать Carbon для ваших дат и датыматематика
  2. найти следующий / предстоящий день рождения пользователя
  3. помните, что формат Ymd обычно подразумевает время 00: 00: 00.
$now = Carbon::now();
$customers = Customer::all();

// find next birthday for each customer
foreach ($customers as $customer) {
    $curyear_bd = Carbon::createFromFormat('Y-m-d', $customer->date_of_birth)->setYear($now->year);
    $now > $curyear_bd->endOfDay() ? $next_bd = $curyear_bd->addYear(1) : $next_bd = $curyear_bd;

    if ($now <= $next_bd->startOfDay() && $next_bd <= Carbon::now()->addDay(7)->endOfDay())
    {
        print "customer $customer->name has birthday coming up\n";
    }
}

Решение MySQL

Вы можете использовать запрос SQL примерно так:

select * from customers where
if (
CURDATE() >= date_add(date_of_birth, interval  TIMESTAMPDIFF(YEAR, date_of_birth, CURDATE())    year), 
             date_add(date_of_birth, interval (TIMESTAMPDIFF(YEAR, date_of_birth, CURDATE())+1) year), 
             date_add(date_of_birth, interval  TIMESTAMPDIFF(YEAR, date_of_birth, CURDATE())    year)
)
between
curdate()
and
date_add(curdate(), interval 7 day);

, но я бы опасался часовых поясов (сервер, клиент и т. Д.).Это может оправдать его собственный вопрос SO ...

Я нашел TIMESTAMPDIFF из Получите разницу в годах между двумя датами в MySQL в виде целого числа

1 голос
/ 20 июня 2019

Вы можете попробовать прочитать статью laravel ORM .

Используйте whereBetween для выбора даты, а использование Carbon date проще для чтения.

return $this->model
        ->whereBetween('dateOfBirth_Column', [Carbon::today()->toDate(), Carbon::today()->addDays(7)->toDate()])
        ->orderBy('dateOfBirth_Column')
        ->get();

Hopeэто помогает.

0 голосов
/ 20 июня 2019

Использование точной даты

$ customerlist = Customers :: whereDate ('date_of_birth', '<=', Carbon :: today () -> addDays (7)) -> get ();

0 голосов
/ 20 июня 2019

одно из возможных решений - это

$ customerlist = Customers :: whereRaw ("date_of_birth BETWEEN NOW () И DATE_ADD (NOW (), INTERVAL 7 DAY") -> get ()

0 голосов
/ 20 июня 2019

Я добавил необработанный запрос, проверьте, работает ли он или нет, и дайте мне знать

 $customerslist=Customers::WhereRaw(' date_of_birth >= DATEADD(day,-7, GETDATE())' )->get();

Надеюсь, это поможет

...