我正在尝试使用QueryDsl来调用SQL语句,Spring Data JPA无法涵盖它。 这是我想要的句子。
SELECT timestamp, deviceId
FROM EventData a
INNER JOIN
(SELECT max(timestamp) timestamp, deviceId
FROM EventData
GROUP BY deviceId) b
USING (timestamp,deviceId)
WHERE deviceId in ('1', '2')
我确实如下:
@PersistenceContext
EntityManager em;
JPAQuery query = new JPAQuery(em);
QEventData eventData = new QEventData();
return
query.from(eventData)
.innerJoin(
query.from(eventData)
.groupBy(eventData.deviceId)
.list(eventData.deviceId, eventData.timestamp.max())
).on(eventData.deviceId.eq(?))
.where(eventData.deviceId.in("1", "2"))
.list(eventData);
我不知道我为内心加入了什么。我尝试了QueryDsl示例但找不到合适的示例。我在哪里可以获得QueryDsl的好例子?
谢谢,您的回答将不胜感激。
答案 0 :(得分:1)
这只是一个部分答案,但它对我来说是一个JUnit测试。我使用的是SQL查询,而不是JPA。值得一试:
Connection connection = getConnection();
SQLTemplates dialect = new PostgresTemplates(); // TODO: use appropriate db template
QEventData c = new QEventData("c");
QEventData c2 = new QEventData("c2");
// Use this to hold alias for inner select
PathBuilder<Object[]> c2alias = new PathBuilder<Object[]>(Object[].class, "c2alias");
SQLQuery query = new SQLQuery(connection , dialect);
return query.from(c).innerJoin(
new SQLSubQuery().from(c2)
.groupBy(c2.deviceid)
.list(c2.device, c2.timestamp.max().as("timestamp")), c2alias
).on(c.deviceid.eq(c2alias.get("deviceid")),
c.timestamp.eq(c2alias.get("timestamp")))
.where(c.deviceid.in(1, 2))
.list(c.deviceid, c.timestamp);
注1:在list()函数中,您必须明确列出要选择的字段,否则您会收到错误,我认为这是由于使用了PathBuilder内部选择别名。
注2:其他帖子表明这可能不适用于JPA,只有SQL:https://groups.google.com/forum/#!msg/querydsl/WDX6oB7Ivsg/0fzoLJA35lgJ
注3:在我编写的SQL中,我没有看到在实践中曾经使用的USING子句,对于那些不了解它的人:http://docs.oracle.com/javadb/10.8.1.2/ref/rrefsqljusing.html
注4:如果上述内容不适用于querydsl / JPA,则考虑重构查询以使用EXISTS子句。