2014-04-09 191 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