JPQL / SQL获取按列分组的最新记录

时间:2015-12-30 09:35:20

标签: java postgresql jpa jpql greatest-n-per-group

我目前正在使用带有postgresql数据库的JPQL(我认为是最新版本),并且我试图通过某些(不是所有列)将最新对象分组。

我们说我有一张MyTable这样的表:

id | name | color | shape | date_of_creation | other_stuff|
---+------+-------+-------+------------------+------------+
01 | apple|    red| circle|        30/12/2015|       stuff|
02 | apple|    red| circle|        15/12/2015|   somestuff|
03 | apple|  green| circle|        01/12/2015|anotherstuff|
04 |   box| orange|  cubic|        13/12/2015|   blahblah1|
05 |   box| orange|  cubic|        25/12/2015|   blahblah2|

我只想要按名称,颜色和形状分组的最新组合:

id | name | color | shape | date_of_creation | other_stuff|
---+------+-------+-------+------------------+------------+
01 | apple|    red| circle|        30/12/2015|       stuff|
05 |   box| orange|  cubic|        25/12/2015|   blahblah2|

让我们假设java等价物是具有相同元素的MyClass。

我在JPQL中的查询看起来像是:

SELECT m FROM MyClass m GROUP BY m.name, m.color, m.shape ORDER BY m.date_of_creation;

但这不起作用,因为" date_of_creation"必须在" GROUP BY"条款,没有意义,因为我不想按date_of_creation分组。我尝试使用嵌套选择,但我现在有同样的问题..

我在找到问题之后,在SO的标题建议中发现了关于每组最大问题(SQL Select only rows with Max Value on a Column),所以我创建了一个这样的命名查询:

SELECT m FROM Myclass LEFT JOIN m.id mleft WHERE 
    m.name = mleft.name AND 
    m.color = mleft.color AND
    m.shape = mleft.shape AND
    m.date_of_creation < mleft.date_of_creation AND
    mleft.id = null

哪个使java.lang.NullPointerException at org.hibernate.hql.internal.ast.HqlSqlWalker.createFromJoinElement(HqlSqlWalker.java:395)或甚至不起作用(没有错误,没有)。我认为这是因为该领域&#34; id&#34;与自己没有关系。使用带有select内部的内部联接似乎在JPQL中不起作用:

SELECT m FROM MyClass INNER JOIN (SELECT mInner from Myclass GROUP BY m.name etc.)

也许我错过了一些东西,我不得不构建一个更复杂的查询,但JPQL似乎不够强大,或者我不太了解它。 另外,我真的不想使用query.getResultList()并在java中完成工作......

欢迎任何提示,提前谢谢。

1 个答案:

答案 0 :(得分:2)

您不能在JPQL中的FROM块中使用子查询,只允许SELECT和WHERE块。试试这样:

SELECT m 
FROM Myclass m
WHERE m.date_of_creation IN ( SELECT MAX(mm.date_of_creation)
    FROM Myclass mm
    WHERE mm.id = m.id)

P.S。代码未经测试