在我的数据库架构中,我与几封电子邮件进行了对话。我想从对话列表中获取最新的电子邮件。在PostgreSql中查询:
select distinct on (conversation_id) *
from email
where conversation_id in (7085214, 7084964)
order by conversation_id, processing_date desc
OpenJPA的:
(List<Email>) entityManager.createQuery("SELECT
distinct(email.conversation.id), email FROM Email email WHERE
email.conversation.id in :id ORDER BY email.conversation.id,
email.processingDate DESC").setParameter("id", conversationIds);
它会在会话中返回会话ID和整个电子邮件列表的地图。
我怎么能做对吗?
由于
答案 0 :(得分:0)
使用本机SQL。
实现所需功能的唯一方法是为OpenJPA开发一个补丁,“教会”它如何在其JPQL解析器和查询生成器中使用PostgreSQL扩展DISTINCT ON
。大多数ORM通过方言挂钩接受此类扩展。不要指望这是一项简单的任务 - 除非您正在编写这些查询的批次,否则本机SQL几乎肯定会更容易。
您不能只使用DISTINCT
或DISTINCT ON
之类的功能。他们不是;它们是完全独立的语法。 JPQL引擎会尝试将其转换为在运行时失败的真正函数调用 - 或者在distinct on
的情况下,只是无法在第一时间解析它。
BTW,DISTINCT ON
有点像GROUP BY
在某些其他供应商数据库(如MySQL)中,您可以在SELECT
中指定未出现在GROUP BY
中的列{1}}或聚合。所以在MySQL中人们可能只是通过生成一个MySQL接受的技术上无效的查询来做到这一点 - 很可能OpenJPA JPQL处理程序不会注意到这个问题,所以它会通过它来完成它。这个技巧不适用于DISTINCT ON
,而PostgreSQL严格遵守GROUP BY
的标准,它不会让您使用GROUP BY
生成非确定性查询。