Запрос SQL и JPQL — поиск по всем записям, группирующимся по параметру с заданной датой

#sql #database #select #jpql

#sql #База данных #выберите #jpql

Вопрос:

У меня есть таблица, которая выглядит примерно так:

введите описание изображения здесь

Я хочу создать запрос для поиска всех записей из этой таблицы с заданной датой (скажем, 5.12.2019) и с более ранними датами, но группировать по materialID .

Пример: выберите все материалы с датой 6.12.2019 должны отображаться все материалы с этой датой (или материалы с более ранними датами) группировка по идентификатору материала с наибольшей датой Результат должен выглядеть следующим образом:

введите описание изображения здесь

Проблема: я хочу сгруппировать свои результаты по идентификатору материала с наибольшей датой. Итак, в этом примере я не хочу показывать материалы с тем же идентификатором с более ранними датами.

Для того же примера:

введите описание изображения здесь

Вопрос: Как создать подобный запрос, используя SQL, а также JPQL? Поскольку я хотел бы использовать этот запрос в режиме гибернации, мне также нужен запрос JPQL.

Спасибо за вашу помощь.

Ответ №1:

Это частный случай запроса «top N для каждой категории». Вы хотите показать максимальную дату для каждого идентификатора материала. В SQL (также будет работать в JPQL):

 SELECT SUM(Amount), SUM(Price), MaterialId, MAX(Date)
FROM t
GROUP BY MaterialId
 

Обратите внимание, что с помощью этого метода вы также не можете отображать идентификатор или MAX (ID), поскольку идентификаторы и даты не обязательно монотонно увеличиваются. Если вы все еще хотите, чтобы идентификатор отображался, как в вашем примере, тогда напишите этот SQL-запрос (я не думаю, что это можно сделать в JPQL):

 SELECT MAX(ID), SUM(Amount), SUM(Price), MaterialId, MAX(Date)
FROM (
  SELECT last_value(ID) OVER (
    PARTITION BY MaterialId 
    ORDER BY Date, ID 
    RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
  ) AS ID,
  Amount,
  Price,
  MaterialId,
  SELECT last_value(Date) OVER (
    PARTITION BY MaterialId 
    ORDER BY Date, ID 
    RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
  ) AS Date
  FROM t
) t
GROUP BY MaterialId