如何将以下查询转换为JPA查询:
select * from (select * from t1 where id=14 order by timestamp desc) as h group by hnumber order by timestamp desc limit 0, 15
我尝试过像下面这样做,但语法错误失败了。
select m from (select n from t1 n where n.id=:id order by timestamp desc) as m group by hnumber order by timestamp desc limit 0, 15
请纠正我,基本上我需要按时间戳的降序获取不同的记录。任何帮助表示赞赏。
更新: t1表中的列是:
seq
id
message
timestamp
hnumber
基本上我需要按时间戳的降序为id(id就像用户)和hnumber(可以是多个)获取不同的行。 id和hnumber中的时间戳应该更大。
请注意:插入t1表的顺序可能不是时间戳的顺序。每个ID都可以有不同的消息。
更新2:
以下是一个例子:
Seq id message timestamp hnumber
1001 14 xyz1 1394607463000 0429c3866c19981fc276855ff3cdaf100e0c9fdb
1002 14 xyz2 1394608378000 0429c3866c19981fc276855ff3cdaf100e0c9fdb
1003 14 xyz1 1394453678000 0429c3866c19981fc276855ff3cdaf100e0c9fdb
1004 14 xyz2 1394608520000 0429c3866c19981fc276855ff3cdaf100e0c9fdb
1005 14 xyz9 1394612791000 369d7cf7bd90fac78ef635b188e2a9952d77a8d1
1006 14 xyz7 1394608513793 0429c3866c19981fc276855ff3cdaf100e0c9fdb
1008 14 xyz6 1394608513793 0429c3866c19981fc276855ff3cdaf100e0c9fdb
1009 14 xyz3 1394622221000 369d7cf7bd90fac78ef635b188e2a9952d77a8d1
1010 14 xyz4 1394608513793 369d7cf7bd90fac78ef635b188e2a9952d77a8d1
我期待的输出:
Seq id message timestamp hnumber
1009 14 xyz3 1394622221000 369d7cf7bd90fac78ef635b188e2a9952d77a8d1
1004 14 xyz2 1394608520000 0429c3866c19981fc276855ff3cdaf100e0c9fdb
答案 0 :(得分:0)
此查询存在多处错误,例如LIMIT
是MySQL特定的语法。您可以改用query.setFirstResult(0)
和query.setMaxResults(15)
。
但更大的问题是子查询仅在SELECT和WHERE子句中受支持,而不在FROM中。请参阅here。
您可能需要考虑使用上面的纯SQL版本并将其传递给createSqlQuery(String)
(或createNativeQuery(String)
如果您正在使用EntityManager
API)。
请注意,这些本机SQL查询不能移植到不同的RDBMS。
答案 1 :(得分:0)
您可以将其写为HQL相关子查询,以避免在from子句中使用连接。例如以下查询将返回给定id
的每个hnumber的最新消息select um.id,um.hnumber,um.message from UserMessage as um
where um.timestamp in (
select max(timestamp) from UserMessage um1
where um1.id=:id and um1.hnumber=um.hnumber group by id,hnumber
)
您没有指定用于映射表T1的实体的名称,因此在上面,我已将其称为" UserMessage"。
获取整个表的结果的一般形式是:
select um.id,um.hnumber,um.message from UserMessage as um
where um.timestamp in (
select max(timestamp) from UserMessage um1
where um1.id=um.id and um1.hnumber=um.hnumber group by id,hnumber
)
你可以看到内部子查询是一个相关的子查询,因为它引用了外部查询中的元素 - um.id和um.hnumber。
我在github上放了一个这个查询的工作示例:
https://github.com/hedleyproctor/hibernate-mapping-and-query-examples
如果您查看Tests类,您将看到一个名为" hqlWithCorrelatedSubquery"的测试。它使用上面的示例数据,并将输出显示为:
Printing results for query against entire table:
14
0429c3866c19981fc276855ff3cdaf100e0c9fdb
1394608520000
xyz2
14
369d7cf7bd90fac78ef635b188e2a9952d77a8d1
1394622221000
xyz3
作为一般规则,许多涉及from子句中的连接的简单SQL表达式可以重写为相关子查询,以允许它们转换为HQL或Hibernate Criteria查询。理论上,如果相关子查询在一个范围内执行,则相关子查询可能会很慢,因为与连接不同,相关子查询应该"对外部结果集中的每一行重复进行评估,但实际上,许多数据库查询优化器将以与等效连接查询相同的方式处理它,方法是在单个操作中将内部查询结果创建为查找表,因此性能将是完全相同的。