Java: SELECT query in INNER JOIN - java

Following SQL query works perfectly fine in Postgres. It returns all latest trainings of a given exercise.
SELECT th.id, th.date, th.exercise_id
FROM Training th
INNER JOIN (
SELECT exercise_id, MAX(date) AS maxdate
FROM Training
GROUP BY exercise_id
) AS tm ON tm.exercise_id = th.exercise_id AND th.date = tm.maxdate
The problem is that Java JPA fails with
java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException unexpected token: (
after the INNER JOIN for the following code example.
String queryString = "SELECT th FROM TrainingHistory th INNER JOIN ( SELECT tm.exercise, MAX(date) as maxdate FROM TrainingHistory group by exercise ) AS tm on (tm.exercise = th.exercise AND th.date = tm.maxdate) WHERE th.accountId = 0";
What am I missing?

Related

Convert SQL Query to Criteria Query in Spring Boot

I'm relatively new to Spring JPA CriteriaQuery. Im trying to convert my old native query in my program to criteria query and haven't been successful on join query for multiple table with conditions. I need help converting native SQL query into Criteria Query for these query below :
select * from student s inner join (
select distinct on (student_id) * from class where status = 'Active' order by
student_id,date_register desc) c on s.id = c.user_id
inner join teacher t on t.subject_id = c.subject_id
where t.status = 'Active' and s.status='Active' order by s.name desc
Update :
Below code is as far as I can go cause I dont really know much. Am i in the right direction? I'm opting for Expression because i dont know how to use Join.
CriteriaQuery<Student> query = cb.createQuery(Student.class);
Root<Student> sRoot= query.from(Student.class);
query.select(sRoot);
Subquery<Integer> subquery = query.subquery(Integer.class);
Root<Class> cRoot= subquery.from(CLass.class);
Expression<Integer> max = cb.max(cRoot.get("dateRegister"));
subquery.select(max);
subquery.groupBy(cRoot.get("student"));
query.where(
cb.and(
cb.in(cRoot.get("dateRegister")).value(subquery)
)
);
Thanks in advance!

JPA unknown column alias in 'group statement'

I got an error while running this query on java SQL but it works when I tested it on SQL editor
#Query(value = "SELECT l.loan, max(i.date) as dDate, tr.collecty, sum(i.expectedAmount) as amount,"
+ "(select CASE WHEN (br.stype = 'x') THEN br.idNumber ELSE br.np END as type from Bower br inner join Leds ld on br.id = ld.bowerId where ld.loan = :loan) as bId "
+ "FROM Loan l INNER JOIN Inst i ON l.loan = i.loan INNER JOIN TList tr ON l.loan = tr.loan WHERE l.loan = :loan GROUP BY l.loanId, tr.collecty, bId")
and got error
Caused by: java.sql.SQLSyntaxErrorException: Unknown column 'bId' in 'group statement'
how to fix it?
The order of execution of group by is before the select in a query. So, at the time you group by bId, the select query is not executed yet and it won't recognize bId column or any alias that you specify at select.
Since bId is a derived column, you can not perform aggregation using the column at the same level. You need to go one level above. Below code should work. However there is still a scope to improve the way aggregation is being performed.
#Query(value = “SELECT loan, dDate, collecty, amount, bId FROM (SELECT l.loan, max(i.date) as dDate, tr.collecty, sum(i.expectedAmount) as amount,"
+ "(select CASE WHEN (br.stype = 'x') THEN br.idNumber ELSE br.np END as type from Bower br inner join Leds ld on br.id = ld.bowerId where ld.loan = :loan) as bId ) "
+ "FROM Loan l INNER JOIN Inst i ON l.loan = i.loan INNER JOIN TList tr ON l.loan = tr.loan WHERE l.loan = :loan ) GROUP BY loan, dDate, collecty, amount, bId”)

HQL does not accept update SQL with join

I need to run this SQL in my java application to a MySQL database:
update group_table
join
(
select tab1.letter, tab1.id_group_table from
(
select letter,
id_group_table,
count(letter) as occurrences
from letter
group by id_group_table, letter
order by occurrences desc
) tab1
group by tab1.id_group_table having max(tab1.occurrences)
) tab2 on group_table.id_group_table = tab2.id_group_table
set champion = tab2.letter
where group_table.id_whatever in (1,2,3,4);
It works if I try it in the database. Now here's what I'm trying to do using hibernate:
String hqlUpdate = "update group_table join (select tab1.letter, tab1.id_group_table from (select letter,id_group_table, count(letter) as occurrences from letter group by id_group_table, letter order by occurrences desc) tab1 group by tab1.id_group_table having max(tab1.occurrences)) tab2 on group_table.id_group_table = tab2.id_group_table set champion = tab2.letter where group_table.id_whatever in (1,2,3,4);";
getSession().createQuery( hqlUpdate ).executeUpdate();
And here is the error I'm getting:
Ago 04, 2014 12:16:18 AM org.hibernate.hql.internal.ast.ErrorCounter reportError
ERROR: line 1:38: expecting "set", found 'JOIN'
line 1:38: expecting "set", found 'JOIN'
at antlr.Parser.match(Parser.java:211)
at org.hibernate.hql.internal.antlr.HqlBaseParser.setClause(HqlBaseParser.java:414)
I need to run this exact query...
How can I do that with hibernate?
THanks!!
Try following code
String hqlUpdate = "update group_table join (select tab1.letter, tab1.id_group_table from (select letter,id_group_table, count(letter) as occurrences from letter group by id_group_table, letter order by occurrences desc) tab1 group by tab1.id_group_table having max(tab1.occurrences)) tab2 on group_table.id_group_table = tab2.id_group_table set champion = tab2.letter where group_table.id_whatever in (1,2,3,4);";
getSession().createSQLQuery( hqlUpdate ).executeUpdate();
If you need exact query then don't use HQL, use native query support instead.

why this strange behavior of OpenJpa?

why do this query works directly on postgres database:
select m from medicine_case m WHERE m.id IN (select m.id FROM medicine_case m LEFT OUTER JOIN patient ON m.patient=patient.id ORDER BY patient.surname ASC )
AND in OpenJpa with the exact corresponding typed query:
String sql = " select m from medicine_case m WHERE m.id IN (select m.id FROM medicine_case m LEFT OUTER JOIN "
+ "patient ON m.patient=patient.id ORDER BY patient.surname ASC )";
TypedQuery<MedicineCase> query = persistenceClient.createQueryMC(sql);
setParameter(query);
query.setFirstResult(first);
query.setMaxResults(count);
gives me:
org.apache.openjpa.persistence.ArgumentException: Encountered "m . id IN ( select m . id FROM medicine_case m LEFT OUTER JOIN patient ON" at character 37, but expected: ["(", ")", "*",.... etc etc
why????? it's so strange and makes me crazy!
the code that creates the query from entity manager:
return entityManager.createQuery(sql, MedicineCase.class);
and the code that executes it:
return query.getResultList().iterator();
You're confusing SQL (which is what PostgreSQL expects) and HQL (which is what EntityManager.createQuery() expects).
Those are two different languages. SQL works with tables and columns, whereas JPQL works with JPA entities, fields/properties and associations, and is translated by your JPA implementation into SQL.
If you want to execute SQL, you must use EntityManager.createNativeQuery().
in jpql it becomes a bit different:
String sql = "select m from " + MedicineCase.class.getSimpleName() + " m WHERE m.id IN :mcList";
TypedQuery<MedicineCase> query = persistenceClient.createQueryMC(sql);
query.setParameter("mcList", persistenceClient.executeQueryMCId(persistenceClient.createQueryMCId(createSql()
+ addOrders())));
setParameter(query);
query.setFirstResult(first);
query.setMaxResults(count);
return persistenceClient.executeQueryMC(query);
where createSql returns:
sql.append("select m.id ").append(" FROM ").append(MedicineCase.class.getSimpleName()).append(" m");
and addOrders:
" LEFT OUTER JOIN m.patient p ORDER BY p.surname ASC

Trouble converting SQL Query into JPQL (Eclipselink)

Hey guys, I have the following query and for the life of me I can't seem to translate it into JPQL. The working SQL is:
select * from TB_PRINT_DETAIL y inner join
(select JOB_ID,max(COPY_NUM) MAX_COPY_NUM from TB_PRINT_DETAIL group by JOB_ID ) x
on y.JOB_ID = x.JOB_ID and y.COPY_NUM = x.MAX_COPY_NUM
My feeble attempt at translating it is as follows:
select o from PrintDetailEntity o inner join (select o2.jobId, max(o2.copyNumber) as
maxCopyNum from PrintDetailEntity o2 group by o2.jobId ) as x on o.jobId = o2.jobId and
o.copyNum = o2.maxCopyNum where o.printSuppressionReasonEntity is null
Thanks in advance for any light you can shine!
If I understand your query right (select entities that have the biggest copyNumber among the entites with the same jobId), the following should work:
SELECT o
FROM PrintDetailEntity o
WHERE o.copyNumber =
(SELECT MAX(e.copyNumber) FROM PrintDetailEntity e WHERE o.jobId = e.jobId)

Categories

Resources