2014-04-09 156 views
0

如何转换下面的查询JPA查询:JPA:转换SQL查询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

请您可以显示表格t1中的列和数据示例以及您期望返回结果的内容?你确定你需要内部选择的“排序”吗?当然,它不会有任何影响,因为你没有对内部选择应用限制。当然,只有外部选择的顺序和限制才会影响结果? – Hedley

+0

@Hedley我更新了我的帖子。请检查。 – User12111111

+0

感谢您的信息。请你可以给出一个(说)10行数据的样本,然后显示你期望得到的结果作为查询的结果,以便我能理解你试图实现的排序? – Hedley

回答

0

有多种事情不对的查询,例如LIMIT是MySQL特定的语法。您可以改为使用query.setFirstResult(0)query.setMaxResults(15)

但是更大的问题是子查询只在SELECT和WHERE子句中支持,而不在FROM中支持。见here

您可能需要考虑使用上面的普通SQL版本,并将其传递到createSqlQuery(String)(或createNativeQuery(String),如果您使用的是EntityManager API)。

请注意,那些原生SQL查询不可移植到不同的RDBMS。

+0

是的,我使用EntityManager。我了解JPA中的LIMIT支持。如果我尝试在第一篇文章中使用本地查询,则会发生死锁。不知道为什么。我只是想用createSqlQuery来代替。我试图将上述查询转换为JPA查询。 – User12111111

0

您可以将其写为HQL相关子查询,以避免在from子句中加入连接。例如下面的查询将返回最近的每个hnumber的消息为给定ID

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

如果您在测试类看,你会看到一个名为“hqlWithCorrelatedSubquery”的考验。它使用从上面的样本数据,并给出了输出为:涉及在FROM子句可以改写为相关子查询联接,以使他们能够

Printing results for query against entire table: 
14 
0429c3866c19981fc276855ff3cdaf100e0c9fdb 
1394608520000 
xyz2 
14 
369d7cf7bd90fac78ef635b188e2a9952d77a8d1 
1394622221000 
xyz3 

一般来说,许多简单的SQL表达式转换为HQL或Hibernate Criteria查询。从理论上讲,如果在一个范围内执行相关子查询,相关子查询可能会很慢,因为与连接不同,对于外部结果集中的每一行,都应重复评估相关子查询“应该”,但实际上,许多数据库查询优化器将在与等效连接查询相同的方式,通过在单个操作中将内部查询结果创建为查找表,所以性能将相同。

+0

这个查询实际上是从t1获取所有记录。 – User12111111

+0

我已经添加了一个工作的例子github。请你可以运行它并与你所看到的进行比较。如果你有一个查询不起作用的数据集,请使用更大的样本数据集来更新你的问题,或者分叉github项目并把数据集放在src/test/resources中,我会看一看。谢谢。 – Hedley