Filter records by month and year in Laravel

2

I have a form with a field of type month , which sends a value in the format Y-m to my controller. How do I search the records for the selected month and year?

I'm using l5-repository

I did this, but it does not work:

$date = Input::get('date');
$type = Input::get('type');

$values = $this->repository->findWhere(['type' => $type, 'date' => $date]);

Give the following error:

  

QueryException in Connection.php line 761: SQLSTATE [22007]: Invalid   datetime format: 7 ERROR: invalid input syntax for type date:   "2016-09" (SQL: select * from "values" where "type" = Recipe and   "date" = 2016-09)

I already imagined that I would make this mistake, but I do not know how to make it work. Anyone give a light?

I'm using PostgreSQL database and the date field is in the date same format.

    
asked by anonymous 12.09.2016 / 22:35

2 answers

0

As a date field, you can format the date before the comparison. In your repository create a similar method

// Em MySQL, por usar uma raw
public function findByBatata($type, $date, $format = '%Y-%m') {
    return $this->model
         ->where(\DB::raw("DATE_FORMAT('date', '$format')", '=', $date))
         ->where('type', '=', $type)
         ->get();
}

// Em Postgresql
public function findByBatata($type, $date, $format = 'YYYY-MM') {
    return $this->model
         ->where(\DB::raw("to_char('date', '$format')", '=', $date))
         ->where('type', '=', $type)
         ->get();
}

This may not be very performative since indexes in this field will not be considered.

As pointed out in another answer, you can use a range of dates. Eloquent has the whereBetween method for this:

public function findByBatata($type, $date, $format = 'Y-m') {
    // Considerando data no formato 2016-02
    $dateTime = \DateTime::createFromFormat($format, $date);

    // o primeiro dia do mês hard coded
    $dateStart = $dateTime->format('Y-m-01');

    // t é equivalente ao último dia do mês
    $dateEnd = $dateTime->format('Y-m-t');

    return $this->model
         ->whereBetween('date', [$dateStart, $dateEnd])
         ->where('type', '=', $type)
         ->get();
}

Another option is to duplicate this already formatted field in month and year format, insert an index, and search directly for that new field.

    
12.09.2016 / 23:45
-1

And how is the date stored? Why should the same error also occur in the correct INSERT? How is the bank modeling? Is the date field of type DATE or VARCHAR?

I believe in 2 possibilities.

1 - Do the search with a range with beginning and end of the month, but then depends on how the data in the database.

$date = date('Y-m'); //so exemplo para ficar o ano e mes atual

//precisa adicioanr o range dos dias
$dateStart = date($date.'-01');
$dateEnd = date($date.'-t'); //o t pega o maximo de dias do mes

//ai é so fazer a busca pelo intervalo do mes com base nos daias
echo 'SELECT * FROM "values" WHERE "type" = "Receita" AND (date >= '.$dateStart.' AND date <= '.$dateEnd.' )';

The result will be something like

SELECT * FROM "values" WHERE "type" = "Receita" AND (date >= 2016-09-01 AND date <= 2016-09-30

Then just adapt to the laravel query.

2 - Change the database and put two fields in the table, year VARCHAR(4) and month VARCHAR(2) instead of only 1 of type date and it might be easier to manipulate the data like this.

    
12.09.2016 / 22:58