Currently there is no way to do this. The support for aggregate functions just isn't there. So I ended up simplifying my query, and doing the rest of the results filtering via code (Java). If you're in a similar situation, don't waste your time (and your hair!) trying to make this stuff work, because it just WON'T.
Ebean RawSql Unparsed Query
-
13-06-2023 - |
문제
So since Ebean doesn't support Aggregate function among many other things, I have resorted to trying to get my complex query to work using RawSql
. Furthermore, it turns out that I need to use .unparsed(sql)
as my valid query string will not work with .parse(sql)
.
Here is my code:
final String sql = "SELECT DISTINCT d.user_id, CAST(d.date as DATE) AS date," +
" MAX(d.speed_KPH) OVER (PARTITION BY CAST(d.date as DATE)) AS maxSpeed," +
" AVG(d.speed_KPH) OVER (PARTITION BY CAST(d.date as DATE)) AS avgSpeed" +
" FROM Driver as d" +
" WHERE d.date BETWEEN '" + sdf.format(from) + "' and '" + sdf.format(to) + "'" +
" ORDER BY date DESC";
final RawSql rawSql = RawSqlBuilder.unparsed(sql)
.columnMapping("user_id", "user.userId")
.columnMapping("date", "message.date")
.columnMapping("maxSpeed", "maxSpeed")
.columnMapping("avgSpeed", "avgSpeed")
.create();
final List<MessageAggregate> theList = Ebean.find(MessageAggregate.class).setRawSql(rawSql)
.findList();
Ebean generates the following (valid) query:
SELECT DISTINCT d.user_id, CAST(d.date as DATE) AS date,
MAX(d.speed_KPH) OVER (PARTITION BY CAST(d.date as DATE)) AS maxSpeed,
AVG(d.speed_KPH) OVER (PARTITION BY CAST(d.date as DATE)) AS avgSpeed
FROM Driver AS d
WHERE d.date
BETWEEN '2014-01-02 09:00:00' and '2014-03-12 17:00:00'
ORDER BY date DESC
Which when run in MSSQL Studio produces:
user_id date maxSpeed avgSpeed
4 2014-02-20 74.1 1.1935294117647
311 2014-02-20 74.1 1.1935294117647
314 2014-02-20 74.1 1.1935294117647
347 2014-02-20 74.1 1.1935294117647
... etc ...
When run in Ebean (via PlayFramework 2.2.2):
Caused by: javax.persistence.PersistenceException: Query threw SQLException:Invalid column index 0.
Bind values:[]
I have tried with and without using the .columnMapping
, and found this little (3+ year old nugget here) which suggests that you can using .columnMapping()
, but that they have to be in the correct, linear order, with in my case, they are.
해결책
제휴하지 않습니다 StackOverflow