Subquery with Inner Join in HQL - java

I want to print title from Movies table which has Foreign key Movie_id in Rating table.In rating table we have to get top 10 results based on movie_id occurrence .Since Limit is not allowed in HQL so setMaxResults is used
Query q=session.createQuery("select Title from Movies as M Inner Join ( SELECT Movie_id, COUNT(*) FROM Rating GROUP BY Movie_id ORDER BY COUNT(*) DESC LIMIT 10 ) as R ON M.Movie_id=R.Movie_id").setMaxResults(10);
Exception is:
java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: ( near line 1, column 59 [select Title from com.rahul.model.Movies as M Inner Join ( SELECT Movie_id, COUNT(*) FROM com.rahul.model.Rating GROUP BY Movie_id ORDER BY COUNT(*) DESC LIMIT 10 ) as R ON M.Movie_id=R.Movie_id]
Since HQL doesn't support subquery how to achieve it ?

You can write this query as a JOIN/GROUP BY:
select m.Title
from Movies m Inner Join
Rating r
on m.Movie_id = r.Movie_id
group by m.Movie_Id, m.Title
order by count(*) desc
limit 10;

Resolved
Query q=session.createQuery("select m.title from Movies m Inner Join Rating r on m.movie_id = r.movie_id group by m.movie_id, m.title order by count(*) desc").setMaxResults(10);

Related

Is it possible to write 'with queries' in jpa specifications

I have native query written with 'with queries'. How could it be rewritten by jpa specifications? It's the small part of code
with sub_query1 as (
select table1.id
from table1
join table2 ON table1.id = table2.contract_id
where table2.administrator_id = 11
order by table1.create_date desc
), sub_query2 as (
select table1.id
from table1
join table3 on table1.id = table3.id
where table3.administrator_id = 11
order by table1.create_date desc
)
select table1.id
from table1
where (table1.id in (select id from esa_subquery) or table1.id in (select id from ec_subquery));
Assuming there is a table1 entity, a table2 entity with contract and administrator relations and a table3 with administrator relation, you can rewrite it like that
select t from table1 where exists (select 1 from table2 t2 where t2.contract.id = t.id and t2.administrator.id = 11) or exists (select 1 from table3 t3 where t3.id = t1.id and t3.administrator.id = 11)

How to execute joins of an entity with the result of a query in Hibernate

I want to run the following SQL in hibernate:
SELECT c.id, c.name, ipc.total
FROM Category c,
(
SELECT comm.category.id as id, count(*) as total
FROM Commerce as comm
GROUP BY comm.category.id
) ipc
WHERE c.id = ipc.id
This is my attempt to write that one in JQL but I get an error. It doesn't seem to like my join against a query result.
Request processing failed; nested exception is java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: ( near line 1, column 86 [SELECT c.id, c.name, ipc.total FROM com.brujulasolutions.directorio.model.Category c,( SELECT comm.category.id as id, count(*) as total FROM com.brujulasolutions.directorio.model.Commerce as comm GROUP BY comm.category.id ) ipc WHERE c.id = ipc.id]
SELECT c.id, c.name, ipc.total
FROM Category c,
(
SELECT comm.category.id as id, count(*) as total
FROM Commerce as comm
GROUP BY comm.category.id
) ipc
WHERE c.id = ipc.id
Hibernate query language does not directly support this type of update join. Instead, we can use a correlated subquery in the select clause:
SELECT c.id, c.name,
(SELECT COUNT(*)
FROM Commerce AS comm
WHERE comm.category.id = c.id) AS total
FROM Category c

Convert Postgres Query to JPQL

How to convert below PostreSQL query into JPQL? I mainly stuck with row_number(), partition and when case.
select p, c from product p left join
(
select
c.product_id, c.id, c.status, c.start_date,
row_number() over (partition by product_id order by (case status when 'EXPIRED' then 2 else 1 end) asc, start_date desc) as row_number
from contract c
order by product_id
) c
on
p.id = c.product_id and c.row_number = 1
order by p.id, c.start_date;

Can I add amounts from multiple tables in hql

I would like to perform a query in HQL similar to this in SQL:
SELECT (
SELECT COUNT(*) FROM EMPLOYER +
SELECT COUNT(*) FROM COMPANIES
)
FROM DUAL
When I add "FROM DUAL" to the query I get an error:
org.hibernate.hql.ast.QuerySyntaxException: DUAL is not mapped
And if I leave off the "FROM DUAL" I get:
org.hibernate.hql.ast.QuerySyntaxException: unexpected end of subtree
Any recommendations?
In SQL, subqueries need their own set of parentheses, so try this:
SELECT ((SELECT COUNT(*) FROM EMPLOYER) +
(SELECT COUNT(*) FROM COMPANIES)
)
If that doesn't work, resort to a from clause:
SELECT e.cnt + c.cnt
FROM (SELECT COUNT(*) as cnt FROM EMPLOYER
) e CROSS JOIN +
(SELECT COUNT(*) as cnt
FROM COMPANIES
) c
Since you didn't join the Company and Employee tables you'd better run two queries:
int companyCount = ((Number) getSession().createQuery("select count(*) from Company").uniqueResult()).intValue();
int employeeCount = ((Number) getSession().createQuery("select count(*) from Employee").uniqueResult()).intValue();
int totalCount = companyCount + employeeCount;
The (Number) is needed since PostgreSQL returns a BigInteger while HDSQLDB returns an Integer, but both are subclasses of Number.

How to join 2 row_numbers

Im trying to do a query where I want to join the row_numbers RN and RN1 so as to remove the duplicate rows as shown BOLD in the result set.
WITH CTE AS (
SELECT
PrevEndDate = LAG(edate,1) OVER (PARTITION BY id ORDER BY id)
, PrevStartDate = LAG(sdate,1) OVER (PARTITION BY id ORDER BY id)
, p.id, p.edate
, ROW_NUMBER() OVER (PARTITION BY p.id ORDER BY p.id) as RN1
FROM table p
)
SELECT
t.id, t.sdate, t.edate
, (ROW_NUMBER() OVER (PARTITION BY t.id ORDER BY t.id)) AS RN
, CTE.RN1
, CASE
WHEN CTE.PrevEndDate > t.sdate
THEN DATEDIFF(day,CTE.PrevStartDate,t.sdate)
ELSE
DATEDIFF(day,t.sdate,t.edate)
END
FROM table t
INNER JOIN CTE ON CTE.id= t.id AND CTE.edate= t.edate
--AND RN1 = RN
Thanks in Advance!
You can't define an alias in the select and then use it in from (or where for that matter). You can move it into a subquery. Something like:
with cte as (. . .)
SELECT . . .
FROM (SELECT t.*, ROW_NUMBER() OVER (PARTITION BY t.PRTCPNT_DCN ORDER BY t.PRTCPNT_DCN) as RN
FROM PRTCPNT_ELIG_SPAN_T t
) t INNER JOIN
CTE
ON CTE.PRTCPNT_DCN = t.PRTCPNT_DCN AND
CTE.PRTCPNT_ELIG_END_DATE = t.PRTCPNT_ELIG_END_DATE AND
CTE.RN1 = t.RN;

Categories