@Don_Conteo

Как правильно составить запрос в базу?

Суть вопроса: из контроллера приходит айди юзера и период (количество месяцев), за который нужно узнать сумму трат.

Вот контроллер:

@GetMapping("{id}/spends")
    public ResponseEntity<Map<String, Double>> getSpendsForUserInPeriod(@PathVariable(value="id") long id,
                                                                @RequestParam(value="period", required = false, defaultValue = "0") int period) {
        return ResponseEntity.ok(recordService.getSpendsForUser(id, period));
    }


В сервисе происходит составление мапы "месяц-сумма":

public Map<String, Double> getSpendsForUser(long id, int period) {
        Map<String, Double> spends = new HashMap<>();
        LocalDate startDate = LocalDate.now();
        for(int i = period; i >= 0; i--) {
            LocalDate endDate = startDate.minusMonths(i);
            String month = String.valueOf(endDate.getMonth());
            double amount = recordRepo.getSpendsForPeriod(id, endDate);
            spends.put(month, amount);
        }
        return spends;
    }


И в репке лежит запрос, который я и не могу сообразить (НЕ РАБОТАЕТ):

@Transactional
    @Query(value="select sum(amount) from records where user_id =:id and date_trunc('month', date) = date_trunc('month', :end_date)", nativeQuery = true)
    double getSpendsForPeriod(@Param("id") long id, @Param("end_date") LocalDate endDate);


Вот, что пишет консоль:

ОШИБКА: функция date_trunc(unknown, unknown) не уникальна
Подсказка: Не удалось выбрать лучшую кандидатуру функции. Возможно, вам следует добавить явные приведения типов.

Прошу знатоков помочь решить проблему. В базе формат ячейки даты просто date, не timestamp
  • Вопрос задан
  • 54 просмотра
Пригласить эксперта
Ответы на вопрос 2
rozhnev
@rozhnev
Fullstack programmer, DBA, медленно, дорого
Попробуйте такой вариант запроса:
select 
  sum(amount) 
from 
  records 
where 
  user_id = 1 
  and date_trunc('month', date) = date_trunc('month', to_date('2021-05-03', 'YYYY-MM-DD'));


PostgreSQL fiddle
Ответ написан
Melkij
@Melkij
PostgreSQL DBA
В принципе не надо так делать фильтр по месяцу через date_trunc.
Напишите обычный
and date >= '2021-04-01' and date < '2021-05-01'
Индекс по btree( user_id, date ) вам наверняка ещё не раз пригодится. А вот городить отдельный btree(user_id, date_trunc('month', date)) под конкретный запрос - зачем, если можно сразу нормально написать сам запрос?

Если лениво считать в коде первый день следующего месяца - попросите это сделать саму базу date '2021-04-01' + interval '1 month'
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы
Kotelov Санкт-Петербург
от 150 000 до 190 000 ₽
от 200 000 до 300 000 ₽
До 350 000 ₽
11 мая 2021, в 07:43
2500 руб./за проект
11 мая 2021, в 07:41
35000 руб./за проект
11 мая 2021, в 06:08
10000 руб./за проект