How do I write this JPQL query with subquery? - java

I'm trying to traduce that SQL sentence
SELECT
operationalobjective.idoperationalobjective,
pno_oo.name
FROM
public.operationalobjective,
public.policynamedobject pno_oo
WHERE
pno_oo.idpolicynamedobject = operationalobjective.idoperationalobjective AND
operationalobjective.idoperationalobjective NOT IN
(
SELECT
operationalobjective.idoperationalobjective
FROM
public.operationalobjective,
public.goal,
public.policy,
public.policynamedobject pno_oo,
public.policynamedobject pno_p
WHERE
goal.idpolicy = policy.idpolicy AND
goal.idoperationalobjective = operationalobjective.idoperationalobjective AND
pno_oo.idpolicynamedobject = operationalobjective.idoperationalobjective AND
pno_p.idpolicynamedobject = policy.idpolicy AND
policy.idpolicy = <number>
);
Having in mind Policy and OperationalObjective both extends PolicyNamedObject, I'm trying to traduce that into JPQL:
SELECT oo FROM OperationalObjective oo
WHERE oo.idoperationalobjective NOT IN
(
SELECT oo.idoperationalobjective
FROM OperationalObjective oo, Goal g, Policy p
WHERE g.policy = :policy AND g.operationalobjective = oo AND p = :policy
)
But when I execute that query via JPA, it raises an exception saying:
ERROR: missing FROM-clause entry for table <<t5>>
SELECT t7.idpolicynamedobject, t7.type, t7.description, t7.name, t0.idoperationalobjective, t0.idobjectivescategory
FROM public.OperationalObjective t0 INNER JOIN public.PolicyNamedObject t7 ON t0.idoperationalobjective = t7.idpolicynamedobject
WHERE (NOT (t0.idoperationalobjective IN
(
SELECT t5.idoperationalobjective
FROM public.OperationalObjective t1 CROSS JOIN public.Goal t2 CROSS JOIN public.policy t3
INNER JOIN public.PolicyNamedObject t4 ON t3.idpolicy = t4.idpolicynamedobject
INNER JOIN public.PolicyNamedObject t6 ON t5.idoperationalobjective = t6.idpolicynamedobject, public.OperationalObjective t5
WHERE (t2.idpolicy = ? AND t2.idoperationalobjective = t5.idoperationalobjective
AND t3.idpolicy = ?) AND t6.type = ?))) AND t7.type = ?} [code=0, state=42P01]
I've executed the SQL sentence using PgAdmin and it retrieved what I wanted, but I don't know what I am doing wrong translating it into JPQL... any idea?
Thank you in advance :)

I suspect you will need to refactor your JPQL statement to use subquery 'EXISTS' as the IN statement doesn't support a sub select. Hopefully this will point you in the right direction.
SELECT oo FROM OperationalObjective oo
WHERE NOT EXISTS
(
SELECT oosub
FROM OperationalObjective oosub
JOIN oosub.goal g
JOIN g.policy p
WHERE <<where conditions>>
)
Oracle docs

Related

Flexible Search Issue SAP Hybris

I have a problem with a Flexible Query. This is my query:
Select
{pp.productCode} as 'Code',
{p.descriptionCics} as 'Desc CISC',
{bs.uid} as 'Store',
{evo.code} as 'Status',
{p.department} as 'Department',
{pca.name} as 'Category',
{p.grm} as 'GRM',
{p.buyerCode} as 'Code Buyer',
{p.buyerids} as 'Buyer',
{ps.planogramCode} as 'Code Planogram',
{pca.categoryCode} as 'Category Planogram',
{s.puvmBlock} as 'Blocked',
(CASE WHEN ({p.productDetailTypeList} is not null )THEN 'YES' else
'NO' END) as 'IMAGE'
from
{
Product as p
JOIN PlanogramProducts as pp on {p.code} = {pp.productCode}
JOIN StockLevel as s on {pp.productCode} = {s.productCode}
JOIN EnumerationValue as evo on {p.status} = {evo.pk}
JOIN PlanogramCategory as pc on {pp.planogramCode} =
{pc.planogramCode}
JOIN PlamnogramCategoryAnag as pca on {pc.categoryCode}=
{pca.categoryCode}
JOIN BaseStore as bs JOIN PlanogramStore as ps on {bs.storeRef} =
{ps.storeRef} AND {bs.bramchOffice} = {ps.branchOffice}
}
WHERE 1=1
and this my error when I execute it:
Can someone help me? Thanks a lot.
Your statement contains errors. You join basestore with planogramStore. But neither planogram store, nor basestore is joined with any other part of your query. You need to join basestore or planogramstore with one of the other tables.
Now you have 2 detached parts in your from statement, which is why you are getting errors
Product as p
JOIN PlanogramProducts as pp on {p.code} = {pp.productCode}
JOIN StockLevel as s on {pp.productCode} = {s.productCode}
JOIN EnumerationValue as evo on {p.status} = {evo.pk}
JOIN PlanogramCategory as pc on {pp.planogramCode} =
{pc.planogramCode}
JOIN PlamnogramCategoryAnag as pca on {pc.categoryCode}=
{pca.categoryCode}
and
JOIN BaseStore as bs JOIN PlanogramStore as ps on {bs.storeRef} =
{ps.storeRef} AND {bs.bramchOffice} = {ps.branchOffice}
you need to have a join between these 2 parts to get the correct data

QueryDSL re-uses table alias for sub-query

I'm having the following simple query:
return new JPAQuery<Job>().from(job)
.where(job.container.id.eq(cid)
.and(job.levels.any().in(levels)))
.fetch();
cid is of type Long, levels is a list of entities.
QueryDSL generates the following SQL:
SELECT t0.x, t0.y, t0.z
FROM job t0
WHERE (((t0.id = 19)
AND EXISTS (
SELECT 1
FROM job t0
JOIN (job_level_mapping t3
JOIN level t2 ON (t2.id = t3.level_id)) ON (t3.job_id = t0.id),
level t1
WHERE ((t1.id IN (74,77)) AND (t2.id = t1.id))))
AND (t0.job_type = 'SUBMIT'));
Note that the table alias t0 for table job is the same for the main query and sub-query. This leads to a wrong query result. If I manually rename the alias from the outer FROM from t0 to tx and also change (t3.job_id = t0.id) inside the sub-query to (t3.job_id = tx.id), then the query works as expected.
Is there some way to tell QueryDSL to use different table aliases for the main query and sub-query? Or is there a different way to write this query?
I'm using QueryDSL 4.1.4.
EDIT:
I'm now using the EntityManager directly with a JPA query and this is
working:
return getEm().createQuery("SELECT DISTINCT job FROM " +
"Job job " +
"WHERE job.container.id = :cid AND job.jobType = :jobType AND job.levels IN :levels", Job.class)
.setParameter("jobType", JobType.SUBMIT)
.setParameter("cid", cId)
.setParameter("levels", levels)
.getResultList();
SELECT DISTINCT t0.x, t0.y, t0.z
FROM job t0
JOIN (job_level_mapping t2
JOIN level t1 ON (t1.id = t2.level_id)) ON (t2.job_id = t0.id)
WHERE (((t0.cid = ?) AND (t0.job_type = ?)) AND (t1.id IN (?,?)));

Java: SELECT query in INNER JOIN

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?

db2 sqlstate 42972 error

I am getting this error when I am trying to execute this sql query
INSERT INTO
AGG_QUALITY
SELECT
QIF.DATEDM_ID,
'Status' AS BREAKDOWN_TYPE,
HCR.VALUE,
QIF.SCANDEFINITION_ID,
QIF.QUALITYISSUE_VALUE,
COUNT(QIF.QUALITYISSUEFACT_ID),
COUNT(QRF.QUALITYRESOLUTIONFACT_ID)
FROM
QUALITYISSUEFACT QIF,
HUBCODERECORD HCR,
ITEMSTATUS ITS
LEFT JOIN
QUALITYRESOLUTIONFACT QRF
ON
QIF.QUALITYISSUEFACT_ID = QRF.QUALITYISSUEFACT_ID
WHERE
QIF.DATEDM_ID > startDateDMId
AND QIF.DATEDM_ID <= endDateDMId
AND HCR.CODE = ITS.H_STATUS_TYPE
AND QIF.DIMENSION_ROM_PK = ITS.ITEMMASTER_ID
GROUP BY
QIF.DATEDM_ID, HCR.VALUE, QIF.SCANDEFINITION_ID, QIF.QUALITYISSUE_VALUE
;
DB21034E The command was processed as an SQL statement because it was not a
valid Command Line Processor command. During SQL processing it returned:
SQL0338N An ON clause associated with a JOIN operator or in a MERGE statement
is not valid. LINE NUMBER=31. SQLSTATE=42972
Try like below with inner joins:
INSERT INTO
AGG_QUALITY
SELECT
QIF.DATEDM_ID,
'Status' AS BREAKDOWN_TYPE,
HCR.VALUE,
QIF.SCANDEFINITION_ID,
QIF.QUALITYISSUE_VALUE,
COUNT(QIF.QUALITYISSUEFACT_ID),
COUNT(QRF.QUALITYRESOLUTIONFACT_ID)
FROM
QUALITYISSUEFACT QIF
INNER JOIN
HUBCODERECORD HCR
ON QIF.DIMENSION_ROM_PK = ITS.ITEMMASTER_ID
INNER JOIN
ITEMSTATUS ITS
ON QIF.DIMENSION_ROM_PK = ITS.ITEMMASTER_ID
LEFT JOIN
QUALITYRESOLUTIONFACT QRF
ON
QIF.QUALITYISSUEFACT_ID = QRF.QUALITYISSUEFACT_ID
WHERE
QIF.DATEDM_ID > startDateDMId
AND QIF.DATEDM_ID <= endDateDMId
GROUP BY
QIF.DATEDM_ID, HCR.VALUE, QIF.SCANDEFINITION_ID, QIF.QUALITYISSUE_VALUE
;
see if it helps
Had the same error here. (note, my Table1 has NO rows)
On my side I could solve it by changing the additional (comma separated) table2 to a REAL inner join.
Example from
select xxx from Table1 t1, Table2 t2
where (t2.col1 = t1.col1) and (t1.col2 = "whatever")
to
select xxx from Table1 t1
INNER JOIN Table2 t2 ON (t2.col1 = t1.col1)
where (t1.col2 = "whatever")
Hope this helps someone else.
(problem occured on DB2 9.7)

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