I have an SQL query:
Select t1.*
From tracking As t1
Inner Join (
Select Max(trackingid) As trackingid, shipid
From tracking
Group By shipid
) As t2 On t1.trackingid = t2.trackingid
How can I execute this query using DynamicQuery?
Aggreed with Kumar. You cannot use JOINS in dynamic query.
Its better to use custom-sql or finder query.
Related
Below is a SQL query with multiple joins and conditions which gives the desired output, I want to convert the below query to HQL
select * from customer c
join customer_geo_rel cg on c.id=cg.customer_id
join geography g on cg.geo_id=g.id
join geo_geo_hierarchy gghCluster on g.id = gghCluster.geo_id
join geo_geo_hierarchy gghDivision on gghCluster.geo_id = gghDivision.parent_geo_id
join role_data_rel rdr on gghCluster.geo_id = rdr.permission_data_id OR
gghDivision.parent_geo_id = rdr.permission_data_id OR
g.id=rdr.permission_data_id
What's the problem? HQL supports the ON clause for joins and if you use a very old version of Hibernate, you can use the WITH clause like e.g. .. join g.roleDataRelList rds on ...
I have two queries that I'm trying to join together.
In first_query TABLE2.PROCESS_ID, every PROCESS_ID is unique in that table. In second_query though there are several PROCESS_ID's with the same number in TABLE3, so I think I have to do a one-to-many join. The join_query I have is giving me an error ORA-00933: SQL command not properly ended which I'm assuming has something to do with the one-to-many relationship with the JOIN.
I'm not really sure how to resolve this. Any help would be much appreciated!
first_query = """
SELECT TABLE1.RULE_ID, TABLE2.STATUS, TABLE2.ERROR_MESSAGE, TABLE2.PROCESS_ID
FROM TABLE2 LEFT JOIN
TABLE1
ON TABLE1.RULE_ID = TABLE2.RULE_ID
WHERE TABLE1.RULE_NAME IN ('TEST1', 'TEST2')
"""
second_query = """
SELECT RECORDS_PROCESSED, PROCESS_ID, STATUS
FROM TABLE3
"""
join_query = """
SELECT RULE_ID, STATUS, ERROR_MESSAGE, PROCESS_ID
FROM (first_query) as query_1
INNER JOIN (second_query) as query_2
ON query_1.PROCESS_ID = query_2.PROCESS_ID
GROUP BY PROCESS_ID desc
"""
You can not select 4 columns and group by only one of them unles you include selected columns as part of aggregation fucntion(like max(), sum(),...). One of the options is this:
SELECT query_1.RULE_ID --1
, query_2.STATUS --2
, query_1.ERROR_MESSAGE --3
, query_1.PROCESS_ID --4
FROM (SELECT TABLE1.RULE_ID
, TABLE2.STATUS
, TABLE2.ERROR_MESSAGE
, TABLE2.PROCESS_ID
FROM TABLE2
LEFT JOIN TABLE1
ON TABLE1.RULE_ID = TABLE2.RULE_ID
WHERE TABLE1.RULE_NAME IN ('TEST1', 'TEST2')) query_1
INNER JOIN (SELECT RECORDS_PROCESSED
, PROCESS_ID
, STATUS
FROM TABLE3) query_2
ON query_1.PROCESS_ID = query_2.PROCESS_ID
GROUP BY query_1.RULE_ID
, query_2.STATUS
, query_1.ERROR_MESSAGE
, query_1.PROCESS_ID
Also please do consider using aliases like this(in your first query):
SELECT T1.RULE_ID
, T2.STATUS
, T2.ERROR_MESSAGE
, T2.PROCESS_ID
FROM TABLE2 T2
LEFT JOIN TABLE1 T1 ON T1.RULE_ID = T2.RULE_ID
WHERE T1.RULE_NAME IN ('TEST1', 'TEST2')
Also, apply the same logic with aliases on your final query or else you will have a different kind of error : "ORA-00918: column ambiguously defined"
Here is a small demo
CTE (i.e. the WITH factoring clause) might help.
WITH first_query
AS (SELECT table1.rule_id,
table2.status,
table2.error_message,
table2.process_id
FROM table2 LEFT JOIN table1 ON table1.rule_id = table2.rule_id
WHERE table1.rule_name IN ('TEST1', 'TEST2')),
second_query
AS (SELECT records_processed, process_id, status FROM table3)
SELECT a.rule_id,
a.status,
a.error_message,
a.process_id
FROM first_query a INNER JOIN second_query b ON a.process_id = b.process_id
GROUP BY you used is invalid; you can't group results by only one column. If results have to be unique, use select distinct. If you have to use group by, specify all columns returned by select (which leads you back to what distinct does), or see whether some column(s) have to be aggregates - in that case, group by makes sense.
Also, you should always use table aliases. Without them, query is invalid as database engine doesn't know which table those columns (if they share the same name) belong to.
I'm in trouble with JPA2 criteria API. Is there any approach to make smth like this with JPA2 criteria API:
SELECT t1.id FROM Table1 t1 INNER JOIN Table2 t2 ON (t1.id = t2.id)
With these rules:
table1 hasn't table2 reference
table2 has table1 reference
the result should be table1 ids
I'm consfused with JPA2 criteria API Root. How to create join in this situation? Should I use two ROOT's : one for JOIN, another for SELECT? please response
Using where
You could do a usual JPQL cross-product join:
SELECT t1.id FROM Table1 t1, Table2 t2 WHERE t2.t1_id = t1.id
JPA support for right joins
JPA does not support right join queries. From here:
Right outer joins and right outer fetch joins are not required to be
supported in Java Persistence 2.0. Applications that use RIGHT join
types will not be portable.
Native SQL query
So another option would be using a native SQL query.
SELECT Table1.id FROM Table1, Table2 WHERE Table2.t1_id = Table1.id
The JPQL query would simply be
select e1.id from Entity2 e2 join e2.entity1 e1
With the criteria API, it would look like this (untested. I hate this API):
CriteriaQuery<String> cq = cb.createQuery(Long.class);
Root<Entity2> e2 = cq.from(Entity2.class);
cq.select(e2.get(Entity2_.entity1).get(Entity1_.id));
I would like to execute this SQL request in QueryDSL JPA
SELECT authorizationitem.*
FROM authorizationitem
INNER JOIN
(
SELECT `authorize`
FROM authorizationitem
GROUP BY `authorize`
HAVING COUNT(*)>1
) a2
ON authorizationitem.`authorize` = a2.`authorize`;
in order to find duplicated row in a table, i should execute this request. But with QueryDSL, i cannot find the way to write this.
It seems QueryDSL does not allow subQuery in Inner Join :s
Any suggestion?
Thanks
regards,
You can't express this with HQL/JPQL, so you will need to expess this with SQL. Querydsl JPA provides the possibility to express both JPQL and SQL queries through its API.
You can try using a subquery in the WHERE clause, but it will probably be less efficient than the subquery in the FROM clause. Make sure there is an index on authorizationitem.authorize to optimize the joins and the GROUP BY.
SELECT authorizationitem.*
FROM authorizationitem
WHERE EXISTS (
SELECT `authorize`
FROM authorizationitem2
WHERE authorizationitem2.authorize = authorizationitem.authorize
GROUP BY `authorize`
HAVING COUNT(*)>1
);
or
SELECT authorizationitem.*
FROM authorizationitem
WHERE (
SELECT count(*)
FROM authorizationitem2
WHERE authorizationitem2.authorize = authorizationitem.authorize
GROUP BY `authorize`
) > 1;
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.