How can i convert the following sql statement to QueryDsl in java? - java

I tried to use querydsl from java code. but when using inner query with more the on column in select clause, I cant approach to specified columns. r.maxTime for example.
FROM (
SELECT Train, MAX(Time) as MaxTime
FROM TrainTable
GROUP BY Train
) r
INNER JOIN TrainTable t
ON t.Train = r.Train AND t.Time = r.MaxTime

Related

QueryDsl-SQL: update with join (not using subqueries)

I am using queryDsl-Sql I need to do an update statement with a join clause like:
update MY_TABLE t1 set t1.MY_FIELD = 'SOME_VALUE'
JOIN MY_TABLE_2 t2 ON t1.FIELD_WITH_FK = t2.ID
where t2.OTHER_FIELD=12324556789 AND t2.OTHER_FIELD like '%something%'
Unfortunately, on queryDsl I was only able to do subqueries during update but not joins:
dsl.update(table1)
.set(my_field, "SOME_VALUE")
.where(
field_with_fk.in(
dsl.select(id).from(table2).where(other_field.eq(12324556789))
, fieldName.like("%something%"));
Which is translated to a subquery (as expected) and happens to take much much more time (difference between 10 seconds using joins and more than 1h using subselects)
I have seen that on JPAUpdateClause is possible to do so but I am not using QueryDsl-jpa here. QueryDSL-SQL has only SqlUpdateClause and I was not able to find how to join different tables when using It.
I think this is more a workaround than a solution, but maybe helps
also others:
dsl.update(table1)
.set(field1, myValue)
.addFlag(
QueryFlag.Position.START_OVERRIDE, //it replaces update by update with join
Expressions.stringTemplate("update {0} join {1} on {2} = {3} #", // I need # to ignore table1 otherwise incorrect SQL
table1, table2, table1FieldWithFkToTable2, table2Id))
.where(other_field.eq(12324556789), fieldName.like("%something%"));
this generates the following SQL:
update table1 join table2 on table1FieldWithFkToTable2 = table2Id #table1
set field1 = myValue
where other_field=12324556789 and fieldName like '%something%'

Error Only from Java Spark ORA-00918: column ambiguously defined

I am trying to run few SQL queries using Java Spark libraries.
All SQLs are running fine except one:
(SELECT CMM.BENEFIT, (length(CMM.HIERARCHY) - length(replace(CMM.HIERARCHY,'>','')) + 1) BNFT_CMPNT_LVL_NBR, LBCX.SERVICE_DEF_TGT_CD, LBCX.SERVICE_DEF_DESC, LBCX.BENEFIT_CMPNT_DESC, LBCX.SERVICE_DEF_TGT_CD, CMM.HIERARCHY FROM EHUB_PROD_RAW.cs90_master_mapping CMM INNER JOIN EHUB_PROD_RAW.wpd_spider_benefit_hierarchy WSBH ON CMM.HIERARCHY = WSBH.HIERARCHY INNER JOIN EHUB_PROD_RAW.legacy_bnft_cmpnt_xref LBCX ON CMM.BENEFIT = LBCX.BENEFIT_CMPNT_NM)
Same query runs fine from SQL Developer!
I am guessing something with hidden char or quotes.
Any guidance please.
You are selecting the same column twice:
( select
cmm.benefit,
( length(cmm.hierarchy) - length(replace(cmm.hierarchy,'>','') ) + 1 ) bnft_cmpnt_lvl_nbr,
lbcx.service_def_tgt_cd,
lbcx.service_def_desc,
lbcx.benefit_cmpnt_desc,
--lbcx.service_def_tgt_cd, <-- this one is duplicated
cmm.hierarchy
from
ehub_prod_raw.cs90_master_mapping cmm
inner join ehub_prod_raw.wpd_spider_benefit_hierarchy wsbh on cmm.hierarchy = wsbh.hierarchy
inner join ehub_prod_raw.legacy_bnft_cmpnt_xref lbcx on cmm.benefit = lbcx.benefit_cmpnt_nm
)
If you need it twice in the result set, then you should use aliases. I think SQL Developer will auto-alias it by appending a _1 to one of the ambiguous columns.

QueryDSL subquery not working

I'm trying to recreate the following SQL query in QueryDSL. The following is my SQL query which is currently working as inteded.
SELECT * FROM room x WHERE unit_id = (SELECT unit_id FROM room WHERE unit_id = x.unit_id GROUP BY unit_id HAVING(SUM(sqft) > 0))
I'm trying to write a QueryDSL query that does the same thing but honestly can't come any further than the bottom query.
JPASubQuery subQuery = new JPASubQuery();
subQuery.from(qRoom).groupBy(qRoom.unit).having(qRoom.sqft.sum().goe(0));
JPAQuery unitquery = from(qRoom)
.where(qRoom.building.eq(building)).where(qRoom.unit.eq(subQuery));
return unitquery.list(qRoom);
The above query isn't working and i'm having trouble using subqueries in QueryDSL. What should I add/change to make this query working?
Fixed it.
I just needed to change .where(qRoom.unit.eq(subQuery)); too .where(qRoom.unit.in(subQuery.list(qRuimte.unit)));

Hibernate 2 with MSSQL for ORDER BY

I have been working with Oracle and Postgre and recently switched to MS SQL 2012.
I use hibernate in my application and wherever I have used the Order by Criteria:
(criteria.addOrder(Order.asc("applicationId")));
It causes an error saying:
aggregate functions dont work.
Once I comment that line out my program works and data can be retrieved.
I'm using Hibernate 3.
Is there any way to order it through hibernate without this error?
edit..
This is one error I get,
Column "SKY.tcrent.RENTNO" is invalid in the ORDER BY clause because
it is not contained in either an aggregate function or the GROUP BY
clause.
Edit 2..
MY query
Query tcSchaduleQ = getSession().createQuery("SELECT SUM(tcs.dueAmount) FROM TrialCalculationSchedule tcs WHERE tcs.facilityId=:facilityId AND tcs.rentalNumber>:rentalNumber AND tcs.dueDate>:dueDate AND dueTypeId IN(:dueTypeId) ORDER BY tcs.rentalNumber ").setInteger("rentalNumber", facility.getPeriod() - noOfprePayments).setInteger("facilityId",facility.getFacilityId()).setDate("dueDate", date).setParameterList("dueTypeId", plist);
Number tcsAmt = (Number) tcSchaduleQ.uniqueResult();
and this is what hibernate generates in HQL
SELECT
SUM(tcs.dueAmount)
FROM
TrialCalculationSchedule tcs
WHERE
tcs.facilityId=:facilityId
AND tcs.rentalNumber>:rentalNumber
AND tcs.dueDate>:dueDate
AND dueTypeId IN(
:dueTypeId
)
ORDER BY
tcs.rentalNumber
and this is the SQL
select
SUM(trialcalcu0_.DUEAMT) as col_0_0_
from
SKYBANKSLFHP.tcrent trialcalcu0_
where
trialcalcu0_.FACID=?
and trialcalcu0_.RENTNO>?
and trialcalcu0_.DUEDATE>?
and (
trialcalcu0_.DUETYPEID in (
? , ?
)
)
order by
trialcalcu0_.RENTNO
Look Like you mix aggregate and non-aggregate expressions .If you are using any aggregate function like AVG() in Select query with some other non-aggregate then you must use Group By ..
Try something like this
createQuery("SELECT SUM(tcs.dueAmount) As DueAmount ...
If you are using Criteria then it should be like this
Criteria crit = sess.createCriteria(Insurance.class);
ProjectionList proList = Projections.projectionList();
proList.add(Projections.sum("investementAmount"));
crit.setProjection(proList);
List sumResult = crit.list();

HQL/SQL/Criteria to join-match all records in a given list while selecting all fields

I'm trying to write a HQL/Criteria/Native SQL query that will return all Employees that are assigned to a list of Projects. They must be assigned to all Projects in order to be selected.
An acceptable way of achieving this with native SQL can be found in the answer to this question: T-SQL - How to write query to get records that match ALL records in a many to many join:
SELECT e.id
FROM employee e
INNER JOIN proj_assignment a
ON e.id = a.emp_id and a.proj_id IN ([list of project ids])
GROUP BY e.id
HAVING COUNT(*) = [size of list of project ids]
However, I want to select all fields of Employee (e.*). It's not possible to define SQL grouping by all the columns(GROUP BY e.*), DISTINCT should be used instead. Is there a way to use DISTINCT altogether with COUNT(*) to achieve what I want?
I've also tried using HQL to perform this query. The Employee and ProjectAssignment classes don't have an association, so it's not possible to use Criteria to join them. I use a cross join because it's the way to perform a Join without association in HQL. So, my HQL looks like
select emp from Employee emp, ProjectAssignment pa
where emp.id = pa.empId and pa.paId IN :list
group by emp having count(*) = :listSize
However, due to a bug in Hibernate, GROUP BY entity does not work. The SQL it outputs is something like group by (emptable.id).
Subquerying the assignment table for each project (dynamically adding and exists (select 1 from proj_assignment pa where pa.emp_id=e.id and pa.proj_id = [anId]) for each project in the list) is not an acceptable option.
Is there a way to write this query properly, preferrably in HQL (in the end I want a List<Employee>), without modifying mappings and without explicitly selecting all columns in the native SQL ?
EDIT: I'm using Oracle 10g and hibernate-annotations-3.3.1.GA
How about:
select * from employee x where x.id in(
SELECT e.id
FROM employee e
INNER JOIN proj_assignment a
ON e.id = a.emp_id and a.proj_id IN ([list of project ids])
GROUP BY e.id
HAVING COUNT(*) = [size of list of project ids]
)
I've found an alternative way to achieve this in HQL, it's far more inefficient than what I'd like, (and than what is really possible without that nasty bug) but at least it works. It's better than repeating subselects for each project like
and exists (select 1 from project_assignment pa where pa.id = someId and pa.emp_id = e.id)
It consists of performing a self-join subquery in order to find out, for each of the Employees, how many of the projects in the list they are assigned to, and restrict results to only those that are in all of them.
select e
from Employee
where :listSize =
(select distinct count(*)
from Employee e2, ProjectAssignment pa
where
e2.id = pa.id_emp and
e.id = e2.id
and pa.proj_id IN :projectIdList
)

Categories