Как фильтровать день рождения только по дням и месяцам и между X днями?

#java #postgresql #spring-boot #jpa

#java #postgresql #пружинный ботинок #jpa

Вопрос:

Учитывая таблицу User с идентификатором, именем и датой рождения, я хочу отфильтровать всех пользователей, которые будут отмечать свой день рождения в течение X дней с сегодняшнего дня, игнорируя год.

Например, если сегодня 24 ноября, я хочу получить всех пользователей, которые отмечают свои дни рождения с 24 по 27 ноября, несмотря на год их рождения.

 LocalDate today = ZonedDateTime.now().toLocalDate();
LocalDate endDay = today.plusDays(3);

-------------------------------------
filter from today to endDay

1 | User A | 11/24/1995
2 | User B | 09/02/2000
3 | User C | 11/26/1998
4 | User D | 11/25/2005
 

В этом случае я хотел бы получить пользователей A, C и D.

Я пытаюсь сделать это, используя аннотацию Java JPA @Query, но если есть способ сделать это в PostgreSQL, это также будет работать нормально.

Ответ №1:

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

Если вы сделаете это, проверив месяц и дату, вам понадобится:

  1. запрос о том, когда период соответствует текущему месяцу
  2. запрос, когда период укладывается в два месяца.

Если вы делаете это, проверяя по дням года (doy) вместо этого, вам придется беспокоиться о переходе на следующий год, а также о том, соответствует ли дата, с которой проверяется, високосному году, является ли дата, которую вы ищете, после високосного дня, а также, если в вашем приложениивы получаете день после високосного дня.

Наконец, вы можете использовать прямое сравнение строк, отформатировав его следующим to_char(birth_date, 'MM-DD') образом. И снова вам понадобятся два запроса о том, когда ваши последние даты перейдут в следующий год. between Проверка включена.

 ... where to_char(birth_date, 'MM-DD') BETWEEN '11-28' AND '12-01'


... where to_char(birth_date, 'MM-DD') BETWEEN '12-29' AND '12-31'
OR to_char(birth_date, 'MM-DD') BETWEEN '01-01' AND '01-02'