Convert a Postgres query into JPQL - postgresql

I have the following query in Postgres:
SELECT *
from table1
LEFT OUTER JOIN table1.table2 ON table1.latest_id = table2.id
WHERE table1.table2.status = 0
AND table1.id NOT IN (
(SELECT id from table3 where userId = table2.user))
I do not have the ability to join table1 and table3 and I am stuck writing the subquery in a format JPA will understand - working with a spring boot app. Here is where I got so far in my repository class:
#Query("SELECT c FROM #{#entityName} c JOIN FETCH c.table2 WHERE c.table2.status = 0")
fun findByIdAndStatus(id: String): MyEntity
I have attempted at the subquery as follows, but with no joy - there is a clear syntax error I cannot wrap my head around:
#Query("SELECT c FROM #{#entityName} c JOIN FETCH c.table2 WHERE c.table2.status = 0" AND c.id NOT IN (" +
"SELECT * FROM Table3 WHERE userId = c.table2.user")
Can you help?
Thank you

Assuming:
your SQL query doesn't utilize any input arguments
table1 is mapped by MyEntity and table3 is mapped by Table3 entity
entity associated with table2 is mapped in MyEntity using latest_id join column
status is mapped as a number (i.e Long / Integer)
You can rewrite the query to following JPQL form:
#Query("SELECT t1 FROM MyEntity t1 "
+ "JOIN t1.table2 t2 "
+ "WHERE t2.status = 0 AND t1.id NOT IN ("
+ " SELECT t3.id from Table3 t3 "
+ " WHERE t3.userId = t2.user "
+ ")")
List<MyEntity> findMyEntities();

Related

What is the proper syntax to alias a join that contains a subquery?

I am trying to alias a JOIN that has a subquery.
RIGHT OUTER JOIN
(
SELECT FieldA, FieldB
FROM Table1
JOIN Table2
ON Table1.WellId = Table2.WellId
) AS wi
AS MProd
ON Units.RS_Unit_Name = RTRIM(wi.RS_POOL) + '-' + wi.RS_Field
I get incorrect syntax near 'AS'...
wi is the alias FieldA & FieldB; How do I alias the RIGHT OUTER JOIN?
My original code was:
RIGHT OUTER JOIN TABLE1
AS MProd
ON Units.RS_Unit_Name = RTRIM(wi.RS_POOL) + '-' + wi.RS_Field
which worked fine. I replaced TABLE1 with a subquery which I did in the code sample. I just can't seem to figure out the proper syntax to set MProd as the alias.
The problem is this line of code:
AS wi AS MProd
This is not valid syntax. It can be AS wi or AS MProd, but not AS wi AS MProd.
This is valid:
RIGHT OUTER JOIN
(
SELECT FieldA, FieldB
FROM Table1
JOIN Table2 ON Table1.WellId = Table2.WellId
) AS MProd
ON Units.RS_Unit_Name = RTRIM(MProd.RS_POOL) + '-' + MProd.RS_Field ...
and so is this:
RIGHT OUTER JOIN
(
SELECT FieldA, FieldB
FROM Table1
JOIN Table2 ON Table1.WellId = Table2.WellId
) AS wi
ON Units.RS_Unit_Name = RTRIM(wi.RS_POOL) + '-' + wi.RS_Field ...

Sql to LINQ query LINQ Query convert

I have a SQL query I want to write in LINQ
Here is my Query
SELECT DISTINCT *
FROM [IHQDB].[dbo].[Table1] as t1
inner join Table2 as t2 on t2.Table2 =t1.ChangedItemID
inner join Table3 as t3 on t3.Table3 = t1.FromUserID
where (t1.FromUserID=1 And t2.ContentItemID= t1.ChangedItemID)
OR (t2.LastModifiedBy=1 or t2.CreatedBy=1 )
Hi now its working fine but My query little bit different on place of 1 I need my userID on base of their First Name and Last Name from M_User table.
How can I get UserId on Base of First Name + Last Name.
Here is my LINQ CODE For Retrieving User Name
linq4 = from q in context.T_ContentItems
join p in context.M_Users on q.CreatedBy equals p.UserID
where (advanceKeyword.Contains(p.EmployeeFirstName + " " + p.EmployeeLastName)) select q;
advancechk12 = linq4.ToList();
========================================================================
What I require is that wherever I have written the value "1" (e.g. t2.CreatedBy=1), I need to find the UserID. For simplicity, I am able to get the names of all the filtered users in the advancechk12. How do I retrieve the UserID's of the list of usernames returned in advancechk12
You have to replace below mentioned Linq query with your models name.I just used the same name of the T-Sql.
var t1List = (from t1 in db.Table1
join t2 in db.Table2 on t1.ChangedItemID equals t2.Id
join t3 in db.Table3 on t3.Id equals t1.FromUserID
where ((t1.FromUserID=1 && t2.ContentItemID= t1.ChangedItemID) || (t2.LastModifiedBy=1 or t2.CreatedBy=1))
select t1).Distinct().ToList();

JPA query additional group by

How to write JPA query for below SQL ?
select * from opstatus o where o.OPERATIONTYPE=2 and o.RECEIVEDFLAG =2 and o.SENDTIME in (select max(o1.SENDTIME)from opstatus o1 where (o1.OPERATIONTYPE=2 and o1.RECEIVEDFLAG =2) group by o1.dn);
Trying to run the below query
result = em.createQuery("select o from DTO o where "
+ "o.operationType=:operationType"
+ " and o.receivedFlag = :receivedFlag"
+ " and o.startTime in (select max(o1.startTime)from DTO o1 where
o1.receivedFlag = :receivedFlag group by o1.Dn) order by o.startTime").
setParameter("operationType","2").
setParameter("receivedFlag", "2").getResultList();
However during runtime below query gets genereated which has additional 'group by T2.DN' for which we get ' org.apache.openjpa.persistence.PersistenceException: ORA-00979: not a GROUP BY expression'
SELECT t0.OPERATIONID, t0.CURRENTSTEP, t0.DETAILEDSTEPS,t0.DN, t0.OPERATIONTYPE, t0.RECEIVEDFLAG, t0.REQUESTID, t0.SENDTIME FROM OPSTATUS t0, OPSTATUS t2 WHERE (t0.OPERATIONTYPE = ? AND t0.RECEIVEDFLAG = ? AND t0.SENDTIME IN (SELECT MAX(t1.SENDTIME) FROM OPSTATUS t1 WHERE (t1.OPERATIONTYPE = ? AND t1.RECEIVEDFLAG = ?) GROUP BY t1.DN)) GROUP BY t2.DN [params=?, ?, ?, ?]
How to prevent additional 'group by' getting appended ? I tried adding 'order by o.sendtime' no use .
Did you means select the last entry in every Dn group. If two different Dn have the same startTime and only one of it is the last(max) your query will fail. Because the o1 in the sub query not linked to the outer o, the OpenJPA will generate FROM OPSTATUS t0, OPSTATUS t2
Maybe you can change your query.
"select o from DTO o where "
+ "o.operationType=:operationType"
+ " and o.receivedFlag = :receivedFlag"
+ " and not exists (select o1 from DTO o1 where
o1.receivedFlag = :receivedFlag and o1.Dn = o.Dn and o1.startTime > o.startTime) order by o.startTime"

Subquery in JPA

I am trying to write the following SQL query as a JPA query. The SQL query works (MySQL database) but I don't know how to translate it. I get a error token right after the first FROM. There are probably other errors here too because I was not able to find any guides on how to do sub-queries in the from part, aliasing and so on.
SQL query
SELECT tbl.* from (
SELECT u.*, COUNT(u.id) AS question_count FROM app_user AS u
INNER JOIN question AS q ON u.id = q.user_id GROUP BY u.id
) AS tbl ORDER BY tbl.question_count DESC LIMIT 10;
JPA query:
SELECT tbl FROM (SELECT u, COUNT(u.id) question_count FROM User u
INNER JOIN u.questions q ON u.id = q.user_id GROUP BY u.id) tbl
ORDER BY tbl.question_count LIMIT 10")
I can't test this with anything right now, but something along the lines of:
final String queryStr = "SELECT u, COUNT(u.id) FROM User u, Questions q WHERE u.id = q.user_id GROUP BY u.id ORDER BY COUNT(u.id) DESC";
Query query = em().createQuery(queryStr);
query.setMaxResults(10);
List<Object[]> results = query.getResultList(); //Index [0] will contain the User-object, [1] will contain Long with result of COUNT(u.id)

How to access a OnetoMany join table in JPQL?

I want to write a lttl complicated query in JPQL where i access a OneToMany Join table. I get QuerySyntaxException: Pan_PanRes is not mapped.
QUERY -
query = "SELECT p FROM Pan p WHERE p.id IN " +
"(SELECT p_id FROM Pan_PanRes p_prs WHERE prs_id IN " +
"(SELECT r.id FROM PRS r where r.pant = :pant))"+
" ORDER BY pr.clD"
i tried implementing this concept in MYSQL. It works fine. So i know i am not calling the join table in right way. How should it be called then?
I would like to add MYSQL statement which works fine -
mysql> select * from pan where id not in
(select pan_id from pan_panres where panres_id in
(select id from panres where pant_id = 3));
Thanks...
Solved it myself -
query = "SELECT p FROM Pan p WHERE p.id IN " +
"(SELECT p.id FROM p.panRes prs WHERE id IN " +
"(SELECT r.id FROM PanRes r where r.pant = :pant))"+
" ORDER BY pr.clD"
Where panRes is the oneToMany variable name i have used in Pan Class.