Domanda

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.

È stato utile?

Soluzione

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top