Aggregate (sum,max,avg) function in Critera API JPA - jpa

In my criteria API query the following query where I query for three columns of my table works.
cq.multiselect(root.get("point").get("id"), root.get("player").get("userid"), root.get("amount"));
but when I want the sum of the column amount using the following query it gives a sql error. The query is
cq.multiselect(root.get("point").get("id"), root.get("player").get("userid"), cb.sum(root.get("amount")) );
The error that I am getting is.
{"id":"6","result":null,"error":"\r\nInternal Exception: com.sap.dbtech.jdbc.exceptions.jdbc40.SQLSyntaxErrorException: [-8017] (at 8): Column must be group column:ID\r\nError Code: -8017\r\n
Please help me with this, as I have been stuck on this for hours now. Thanks

The message is telling you that you need a group by clause in your query. Every column in the select clause (except the ones which are the result of an aggregate function) must be in the group by clause:
criteriaQuery.groupBy(root.get("point").get("id"),
root.get("player").get("userid"))

Related

Spring Data: Getting NonUniqueResult Problem for the query

Hello experts of the world. Need some help concerning executing a query with SpringData.
The expectation is to execute the Query below in the Spring Data annotation by combining with the repository method name (Automated Query Construction) to get a unique result. Apparently it fails from time to time by saying the result is not Unique.
The question here is if the method name is still considered in Query Construction while also executing the query in the annotation.
#Query("SELECT r from Revision r WHERE r.revisionBid = ?1 AND r.revisionStatusId = ?2 ORDER BY r.lastModifiedDate DESC")
Optional<Revision> findFirst(Integer revisionBid, Integer revisionStatusId);
Thanks in advance!
The query creation for limiting to 1 result is defined here with FIRST & TOP included in the method name.
https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.query-methods.query-creation
I don't think "findFirst" will work when you're using an #Query, as the query will be constructed from HQL expression in the #Query rather than the fluent API passing over the method name. Because of this, when the query returns multiple results, it will throw the exception as the Optional is told to wrap a single returned object, not a collection. Add a LIMIT clause to the HQL query and you should be good.

JPA: Group by and select function in Postgres

I have a simple reporting query group by id and day that looks like the following:
select id,
avg(case when name = 'temp' then value end) as average_temp,
DATE_TRUNC('day', timestamp) as day
from data
group by id, day
order by id;
The query basically needs to show the average daily temperature for each asset.
The user is able to specify a bunch of different aggregation functions beyond just 'average', the above is only a simple example. For example, avg temp, max temp, max speed, etc.
I'm trying to translate that into JPA as follows:
CriteriaQuery<Object[]> query = criteriaBuilder.createQuery(Object[].class);
Root<AssetMetricDataPoint> root = query.from(Data.class);
List<Selection<?>> selectionList = getSelections(aggregationQuery, criteriaBuilder, root);
Expression<Instant> groupDate = criteriaBuilder.function("date_trunc", Instant.class, criteriaBuilder.literal("day"), root.get("timestamp"));
selectionList.add(groupDate.alias("day"));
query.multiselect(selectionList);
query.where(getWherePredicates(aggregationQuery, criteriaBuilder, root));
query.orderBy(getOrderBy(aggregationQuery, criteriaBuilder, root));
query.groupBy(root.get("id"), groupDate);
return this.setupPagination(entityManager.createQuery(query), aggregationQuery);
I'm using criteriaBuilder.function to group by the date. However, when I execute the query using JPA I get the following exception:
org.postgresql.util.PSQLException: ERROR: column "data0_.timestamp" must appear in the GROUP BY clause or be used in an aggregate function
This appears to occur because the query is parametized and Postgres doesn't realize that the 'day' parameter that appears in both the select and group by clauses are the same.
Is there any way around this. Can I somehow bake in the 'day' value so it's not sent a parameter? Or some other method?
In the end there's a relatively solution to the problem. Rather than grouping by the expression, I thought I'd try to group by the alias instead: criteriaBuilder.literal("day"). This didn't work, however, with Postgres complaining about a non-integer literal.
I then realised I could group by a positional integer instead, which in my case ended up looking like:
query.groupBy(root.get("id"), criteriaBuilder.literal(selectionList.size()));
This works as expected.

In Talend how to give the tfilerowcount value to input of the MySQL query?

I'm a beginner to Talend. I have stopped at one point in my requirement.
My requirement is I have to pass the filecount value to MySQL query on LIMIT Clause. Ex: if I can get file count from tfilerowcount item in talend. Once received this value, I have to pass it to tMysqlInput query as
select * from table_name limit "+tFileRowCount_1.filecount+";
You can get the number of rows in a file using below
(Integer)globalMap.get("tFileRowCount_1_COUNT")
Hope this would help you out.

JDBC with Microsoft Access - The query return no rows when i use a date in the where clause

here is the code i execute...
dc.rs = dc.st.executeQuery("select count(*) from Accounts where date_join = CDATE(25-11-2012)");
It returns 0 rows even though I have 3 accounts in database that will match this.
The format i use when i insert date is
CDATE(day-month-year)
I tried also this format, but still returns nothing..
CDATE('25-November-2012')
I also use that format when i search using dates. But i can't understand why it returns no rows.
i get this error when I try to use the getDate(1) after I query that..
[Microsoft][ODBC Microsoft Access Driver]Restricted data type attribute violation on column number 1 (Expr1000)
Is there any wrong with my where clause?
Change the where clause to data_join = CDATE('25-11-2012')

Nhibernate Expression.In limit

I am querying the Nhibernate criteria query with more then 2100 values for In clause.
I do something like Session.CreateCriteria(typeof()).Add(Expression.In("fieldName",arrayValue))
Where arrayValue contains more then 2100 values. I face error
Exception occurred:
UnknownError
NHibernate.ADOException: could not execute query ..then the query with more then 3000 values in array.
with some google help we found out that IN clause in Sql supports only till 2100 values.
Does anyone has faced similar issue earlier? We do not want to change the query as it is written in some generic way and not customized one.
This is a limitation of SQL Server. I wouldn't suggest doing this, but if you insist, you could work around it by creating a table-value sql function (see http://www.dzone.com/snippets/function-getting-comma) that splits up a string by commas (or whatever delimiter you want) and returns the values as a table, and then pass in all your ID's as (say) a comma separated list in 1 parameter and use a SQLCriterion in your criteria query.
eg:
criteria.Add(
new SQLCriterion("{alias}.ID IN (SELECT element FROM dbo.GetCSVValues(?))",
new[]{csvListOfIds},
new[]{NHibernateUtil.String}))
You could split the array into multiple batches, query multiple times, and then combine the result.