Hibernate Query - Получить последние версии по метке времени? - PullRequest
2 голосов
/ 02 мая 2010

У меня есть база данных, которая используется как система контроля версий. То есть вместо того, чтобы обновлять какие-либо строки, я добавляю новую строку с той же информацией. Каждая строка также содержит столбец version, который является отметкой времени даты, поэтому единственное отличие состоит в том, что новая строка будет иметь более позднюю отметку времени.

У меня проблемы с написанием эффективного запроса гибернации, который возвращает последнюю версию этих строк. Для примера, это строки в таблице с именем Product, столбец с меткой времени - version. В таблице представлено несколько версий нескольких продуктов. Таким образом, может быть несколько версий (строк) ProductA, несколько версий ProductB и т. Д. И я хотел бы получить последнюю версию каждой из них.

Могу ли я сделать это одним запросом гибернации?

session.createQuery("select product from Product product where...?");

Или для этого потребуются некоторые промежуточные шаги?

Ответы [ 2 ]

2 голосов
/ 02 мая 2010

Чтобы ответить на этот вопрос, каждому продукту нужен какой-то идентификатор. Поскольку может быть несколько версий, нам нужно знать, «что это за продукт», я предполагаю, что product.id отсутствует, поскольку это, вероятно, суррогатный ключ. Я выберу product.name ради примера.

Вот один запрос для получения последней версии каждого продукта:

select p1 from Product p1 where
  p1.timestamp >= all (
     select p2.timestamp from Product p2 where
      p2.name=p1.name
  )

(Мой HQL немного ржавый, но я надеюсь, вы поняли суть.)

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

РЕДАКТИРОВАТЬ: я пересмотрел запрос - я недавно видел, как кто-то использовал синтаксис "on" в сообщении на форуме, но теперь я помню, что это не является допустимым HQL. Извините за это - у меня нет системы для тестирования. Теперь он использует коррелированный подзапрос, который функционирует так же, как JOIN.

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

0 голосов
/ 02 мая 2010

Чтобы найти последнюю версию определенного продукта:

select product where ... order by version DESC

поставить составной ключ тоже с версией.

Чтобы найти последнюю версию всех продуктов, вам нужно два запроса (или подзапрос):

Insert into TMP (id, version) select (id, max(version)) from product group by id);
select P.* Product P, TMP where TMP.ID = P.ID
...