2014-09-05 137 views
0

如何在QueryDSL(Java)中實現組的計數?如何計算QueryDSL中結果組的數量?

背景

我採取一個表,在這裏我想組返回之前的結果分頁搜索。

除了通常的LIMIT x OFFSET y查詢,我還希望收到總行數。

這是一個頁面(簡化)SQL查詢:

SELECT x, y, MAX(z) 
    FROM tasks 
WHERE y > 10 
GROUP BY x, y 
LIMIT 10 OFFSET 0 

要檢索的行數,我試圖用一種天真COUNT(*)代替x, y, MAX(z)這樣的:

SELECT COUNT(x) 
    FROM tasks 
WHERE y > 10 
GROUP BY x, y 

不幸的是,這並不會產生一行與前一個查詢返回的組的數量,而是每組有一行,每行都有分組在一起的行數 - 像往常一樣用於聚合函數,COUNT chan當存在GROUP BY時表示其含義。 (至少在PostgreSQL裏,我們使用的是在這裏。)

我們可以通過使用第一個SELECT語句的子查詢FROM子句中的檢索總數:

SELECT COUNT(*) 
FROM (SELECT x, y, MAX(z) 
     FROM tasks 
     WHERE y > 10 
     GROUP BY x, y 
    ) 

現在困難的部分:我們如何在JPQL和/或QueryDSL中做到這一點?

前兩個查詢是由代碼產生這樣的:

QTask qTask = QTask.task; 
Expression<?>[] groupExps = { qTask.x, qTask.y }; 
Predicate predicate = qTask.y.gt(10); 

List<Result> results = getQueryDSL().createQuery() 
            .from(qTask) 
            .where(predicate) 
            .groupBy(groupExps) 
            .offset(0) 
            .limit(10) 
            .list(ConstructorExpression.create(Result.class, 
                     qTask.x 
                     qTask.y, 
                     qTask.z.max())) 
Long total = getQuerydsl().createQuery() 
          .from(qTask) 
          .where(predicate) 
          .groupBy(groupExps) 
          .singleResult(qTask.x.count()); 

它看起來像JPA/JPQL doesn't support subselects other than in WHERE or HAVING-clauses,即它們不可能在FROM子句。這似乎是JPA的QueryDSL不支持它們的原因。

有沒有辦法重寫這個聲明,或者以某種方式解決這個限制?

+0

我也在尋找類似的問題的解決方案如下圖所示 'SELECT COUNT(*)作爲來自其股票stock0_總和(stock0_.QTY)> col_0_0_從(SELECT COUNT(stock0_.stock_ ID)的計= 10 0)tbl;' 如果你有答案,請讓我知道。 – 2016-08-16 13:43:36

回答

1

我不能幫你出JPA和JQL,但它是一個有趣的問題,SQL ...

什麼關係數據庫管理系統?下面的工作在MS SQL Server中。您可以使用連接,不同和計數來確定連接x和y時有多少個唯一值。當您按x,y分組時,這應該是相同的行數。

select count(distinct CAST(x as char(10)) + CAST(y as char(10))) 
from tasks; 
+0

其實,我得到了一個SQL解決方案,在我的問題中使用了子查詢。我只是有問題如何告訴JPA(和QueryDSL)。 (順便說一下,我使用的是Postgresql。) – 2014-09-05 18:49:02

+0

所以,你實際上連接了這些行,然後在結果上使用「distinct」來查看總計數?我會嘗試一下,如果這可以在QueryDSL中實現,並且它實際上比檢索所有內容並計入客戶端更快。 – 2014-09-05 18:51:43

+0

正確。連接,然後只計算不同的值。我承認這不是一個理想的解決方案,但我只是把在尋找彙總查詢的行數不from子句中的子查詢,你說的是不是有可能在QueryDSL的挑戰。希望它以某種方式幫助。 – KingOfAllTrades 2014-09-05 19:43:47

相關問題