Как создать список уникальных лет между несколькими датами в Lumen/Laravel

я создаю API в Lumen , и мне нужно создать метод, который будет получать даты из двух колумов в одной таблице и возвращать любые годы, которые происходят между этими датами, возвращая их все как один массив.

Например, представьте столбец таблицы с именем start_dateи другой столбец с именемend_date

start_date | end_date          getAllYears() should return =>
                               [1983, 1984, 1985, 1986, 1987,
                               1999, 2000, 2001, 2002, 2003,
                               ..., 2016]
1999-05-09 | 2002-04-03
1983-03-12 | 1987-09-23
2001-02-12 | 2016-11-27

В настоящее время у меня есть метод, который управляет этим на других типах более конкретных запросов, основная проблема с этой попыткой заключается в том, что из-за огромного количества записей SQL, которые я получаю, такой метод, как этот, заставляет мой запрос истекать каждый раз.

Мой неэффективный метод, который мало использует Lumen/Laravel

public function getAllYears(){
    $dates = $this->model->select('data_ini', 'data_fim')->get();

    $results = [];

    foreach ($dates as $obj){
        $carbonBegin = Carbon::createFromDate($obj->data_ini->year);
        $carbonEnd   = Carbon::createFromDate($obj->data_fim->year);

        if($carbonEnd->year === 9999){
            $carbonEnd->year = date('Y');
        }

        $carbonEnd->year++;
        // Simple method that runs a DatePeriod method
        $dateRange = $this->helper->createDateRange($carbonBegin, $carbonEnd);

        $results = array_merge($results, $dateRange);
    }
    sort($results);
    $cleanYears = array_unique($results);

    if ($cleanYears == null)
        return response()->json(['error' => true, 'errorCode' => '1008', 'message' => "No years found!"]);
    else
        return response()->json(['error' => false, 'years' => $cleanYears]);
}

Таким образом, вопрос в том, как я могу сделать это менее дорогостоящим способом, чтобы мой сервер не тайм-аут на каждый запрос? Заранее благодарим за помощь 🙂

Примечание: DB: raw является no-go, поскольку мой TL запретил мне использовать его в любом месте API

1 ответ

  1. Похоже, вам нужен whereBetween:

    $between = DB::table('theTable')->whereBetween('data_ini', ["str_to_date('2011-05-06','%Y-%m-%d')", "str_to_date('2011-05-06','%Y-%m-%d')"])->get();
    

    С моделями:

    $between = $this->model->whereBetween('data_ini', ["str_to_date('2011-05-06','%Y-%m-%d')", "str_to_date('2011-05-06','%Y-%m-%d')"])->get();
    

    В приведенном выше, я использую встроенный MySQLstr_to_date

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