How to convert SQL into HQL having union and inner joins? - java

I wan to convert this plain SQL query to HQL. I have an idea that how to convert SQL queries into HQL queries but my query is containing UNION and then inner join. So it become tricky to convert it for me.
select count(distinct T.id_veicolo) from
((select distinct C.id_veicolo from (
(select distinct id_veicolo from movement
where id_sede_uscita = 23
and annullato <> 'true'
and (((inizio >= '2019-01-05' and inizio <= '2019-01-06') and fine >= '2019-01-06')
or (inizio <= '2019-01-05' and (fine <= '2019-01-06' and fine >= '2019-01-05'))
or (inizio <= '2019-01-05' and fine >= '2019-01-06') or (inizio >= '2019-01-05' and fine <= '2019-01-06')))
UNION
(select id_veicolo from freeVehicle where id_sede = 23 and inizio <= '2019-01-05' and fine >= '2019-01-06') ) as C) as D
inner join (select id from parco_veicoli where targa = 'XXX') as R on D.id_veicolo = R.id) as T
Problem Point
If there is only UNION present in this query then i could convert this query into 2 sub queries but my problem is that after the UNION we again using the inner join. Which is the main problem point for me.
My Requirement
I want same the result from HQL query as i am getting from this SQL query. I do not want to use SQL query because SQL queries doesn't support caching.

In case you need strictly union with inner join then better go for native sql.The resultset can be convereted into POJO objects in a java class.But you will leverage the speed of a native query execution and also just a single db hit.

Related

How to avoid subquery in FROM clause to translate SQL query into hibernate query?

I have a rather simple query that works in standard SQL, but doesn't in HQL :
SELECT id
FROM ( SELECT COUNT(*) as rows,
MESSAGES_ID as id
FROM motcles_message mm
WHERE motcle IN :keyWords
GROUP BY MESSAGES_ID) a
WHERE a.rows = :size
Is there any way for me to avoid using a subquery in the FROM statement since HQL doesn't support it ?
I know it can use subqueries in SELECT and WHERE clauses, but I can't find a solution.
SELECT MESSAGES_ID as id
FROM motcles_message mm
WHERE motcle IN :keyWords
GROUP BY MESSAGES_ID
HAVING COUNT(*) = :size

Convert complex DB2 SQL with ROW_NUMBER() to mongo query

I'm new to MongoDB, I'm trying to convert existing DB2 query to MongoDB. I'm Using Java to run this query.
Current DB2 Query:
SELECT * FROM
(SELECT MBI.*, ROW_NUMBER() OVER Order by PDATE DESC AS rownumber
FROM USER1.COLLECTION1 MBI, USER1.COLLECTION2 IC
WHERE MBI.VISIBILITY = 1 and MBI.MBOXID = '1234'
AND UPPER(MBI.MBOXITID) >= '1234555'
AND UPPER(MBI.CATEGORY) = 'S'
AND UPPER(MBI.Mimetype) = 'PDF'
AND UPPER(MBI.Psystemid) = 'TBA'
AND days(current date) - days(MBI.PDATE) < 20
AND MBI.MBOXITID = IC.ICONTENTID) AS FinalResult
WHERE rownumber BETWEEN 1 and 2 Order by PDATE DESC
Am really not sure how to get the ROW_NUMBER details in MongoDB.
Can you help for me solve problem?
#bharathiraja, hopefully, you've done the migration by now and figured out the steps. you'll have to convert your inner joins to mongodb lookup operator and then remove nulls (because lookup is left-outer-join-operator). From your query, looks like you're trying to paginate using row_number(). In Mongodb aggregation framework, after you've done the sort on the PDATE, you can add the limit and skip operator to paginate.
At Couchbase (where I work), we've built row_number() just like standard SQL. Checkout. https://blog.couchbase.com/on-par-with-window-functions-in-n1ql/

HQL - COUNT on SELECT clause not working

I'm trying to create an HQL query that calculates several stats on a list on specific users for specific dates (for example, how many were logged in etc.). Each stat has a different criteria):
SELECT
COUNT(SELECT u2.id FROM User u2 WHERE u.id = u2.id AND u2.lastLoginDate BETWEEN x AND y),
COUNT(some other stats), ...
FROM User u
WHERE u.managerId IN (...)
While the COUNT(SELECT...) clause worked in MySQL, in HQL I get the following exception:
org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: SELECT
Anyone know how to make it work?
EDIT:
Ok, So according to this suggestion HQL - COUNT on SELECT clause not working now the query looks something like this:
SELECT
COUNT(DISTINCT CASE WHEN u.lastLogin BETWEEN x AND y THEN u.id ELSE null END),
COUNT(DISTINCT CASE WHEN ... END),
SUM(CASE WHEN u.id = p.userId THEN p.amount ELSE null END),
FROM User u, Points p,... WHERE u.managerId IN (...)
Problem is, the calculated SUM is not correct because of the From clause - it's multiplied by the number of tables.
For example if the total sum should be 80, and I have 4 tables in the from clause, the sum is instead 480!
Obliviously, distinct won't work correctly for sum. Any ideas?
It seems that you just want conditional aggregation. It is unclear what you really want from the query, but this may be close:
SELECT COUNT(*) as cnt1,
SUM(CASE WHEN u2.lastLoginDate BETWEEN x AND y THEN 1 ELSE 0 END) as cnt2,
SUM(CASE WHEN some other stats THEN 1 ELSE 0 END), ...
FROM User u
WHERE u.managerId IN (...)
I am surprised that count(select . . . ) worked in MySQL. First, subqueries usually require their own parentheses. Second, in a select, a subquery generally needs to be a scalar subquery. And third, subqueries are generally not allowed as arguments to aggregation functions. Are you sure the construct wasn't select count() . . .?
You can use native SQL.
Here is an example.
String sql = "select {user.*} from User user";
// here creates a hql query from sql
SQLQuery query = session.createSQLQuery(sql);
query.addEntity("user", User.class);
List results = query.list();
//Hibernate modifies the SQL and executes the following command against the database:
select User.id as id0_, User.name as name2_0_ from User user
you can search for Native SQL.
Hope this will help.

How to write complex join query with JPA

How to write this kind of complex join query with JPA, Some of syntax I have denoted below not work with JPA. I have used them for demonstrate way that sql query should build, so sorry about that.
SELECT Result1.name1, Result1.count1, Result2.name2, Result2.count2 FROM (
SELECT
taskOne.user.name AS name1,
COUNT(taskOne.taskId) AS count1
FROM
Task AS taskOne
INNER JOIN
taskOne.defect AS defectOne
WHERE (
defectOne.defId = taskOne.defect.defId
AND
taskOne.taskCategory.tcaId = 1
)
GROUP BY
taskOne.user.usId
) AS Result1
FULL JOIN (
SELECT
taskTwo.user.name AS name2,
COUNT(taskTwo.taskId) AS count2
FROM Task AS taskTwo
INNER JOIN taskTwo.defect AS defectTwo
WHERE (
defectTwo.defId = taskTwo.defect.defId
AND
taskTwo.taskCategory.tcaId = 2
)
GROUP BY taskTwo.user.usId
)
AS Result12
WHERE Result1.name1 = Result12.name2
JPQL is desired for selecting objects. Your query seems incredibly complex, I would recommend a native SQL query, or simplifying it.
JPQL does not support sub selects in the from clause.

CASE statement in HQL or Criteria

derived from this question, is it possible to use HQL or Criteria for the following SQL statement:
SELECT
e.type,
count(e),
count(d),
count (case when gender = 'male' then 1 else NULL end) AS NumberOfMaleEmployees
from Department d
JOIN d.employees e
WHERE e.dead = 'maybe'
GROUP BY e.type
Although google comes up with a few hits that state HQL supports CASE statements, Hibernate 3.6.6 fails with a
QuerySyntaxException: unexpected token: CASE
when I create the query above on an EntityManager instance.
How much of a bad idea is it, to create another query for every e.type to determine the number of males manually, e.g. for every e.type
SELECT
count(e),
from Department d
JOIN d.employees e
WHERE e.dead = 'maybe', e.type = ugly
Since there could be quite a few types, this is potentially slow. I'd like the database to do the work for me.
Well, it seems, case statements are supported:
http://docs.jboss.org/hibernate/core/3.5/reference/en/html/queryhql.html
They just don't seem to work within count(). An alternative would be using sum(case when... then 1 else 0 end) instead

Categories

Resources