I have a pretty simple sql query:
SELECT o.description, oi.description, cu.name
FROM dbo.order o
LEFT JOIN dbo.orderitem oi o.orderItemId = oi.orderItemId
INNER JOIN dbo.customer cu on cu.customerId = o.customerId
WHERE cu.id = 12345
That query works, every time.
If I change the INNER JOIN to a LEFT JOIN...
LEFT JOIN dbo.customer cu on cu.customerId = o.customerId
then it always freezes when I call it with Java (via REST) and sometimes freezes if I am using my SQL Client. Sometimes it just works with the exact same search parameter and returns a few rows (<10) as expected.
Freezes means that it won't even start counting the execution time in my SQL client (SQuirreL) and that it will run into a timeout when I call it in Java.
But it will work again if I add a second WHERE clause like
SELECT o.description, oi.description, cu.name
FROM dbo.order o
LEFT JOIN dbo.orderitem oi o.orderItemId = oi.orderItemId
LEFT JOIN dbo.customer cu on cu.customerId = o.customerId
WHERE cu.id = 12345
AND o.someOtherId = 3456
or remove the cu.id completely.
Does anyone have any clue why that could happen?
I am not getting this line..
LEFT JOIN dbo.orderitem am oi o.orderItemId = oi.orderItemId
Dont you think it should be like:
LEFT JOIN dbo.orderitem oi on o.orderItemId = oi.orderItemId
Can you try?
This is because the left join on customer makes the where clause ineffective; the query would return all orders, with all orderitems, but only for orders of customer 12345, it would also return the customer name.
Maybe you want to do a right join instead, so you get the customer name even if he has no orders?
Related
Working with grails 3.3.8 and Mysql DB 5.5.x version.
I have done this query:
String query = $/
select new Map( i1.id as id,i1.name as name)
from CustomerComposition as c1
inner join c1.instrument as i1
left join i1.analisys as a1,
Instrument as i2
left join i2.analisys as a2,
Instrument as i3
left join i3.analisys as a3
where
i1.id=i2.id and i1.id=i3.id and
c1.portfolio.id=:ptfId and a1.phase.id=:p1Id and a2.phase.id=:p2Id and a3.phase.id=:p3Id
/$
List composition = CustomerComposition.executeQuery(query,
[ptfId: ptfId, p1Id: phase[0], p2Id: phase[1], p3Id: phase[2]])
The left join doesn't work. Then I realize that it doesn't work because I put a clause inside the WHERE. I double check with simple SQL statment and indeed it works once moved the conditional out the where. A simple snip taken just for clarification, before and it did not work:
SELECT
instrument1_.id
FROM
customer_ptf_composition customerpt0_
INNER JOIN instrument instrument1_ ON customerpt0_.instrument_id = instrument1_.id
LEFT JOIN analisys analisys4_ ON instrument1_.id = analisys4_.instrument_id
WHERE
customerpt0_.portfolio_id =1216
AND analisys4_.phase_id =111
and after and it works due to how left/right join works:
SELECT
instrument1_.id
FROM
customer_ptf_composition customerpt0_
INNER JOIN instrument instrument1_ ON customerpt0_.instrument_id = instrument1_.id
LEFT JOIN analisys analisys4_ ON instrument1_.id = analisys4_.instrument_id AND analisys4_.phase_id =111
WHERE
customerpt0_.portfolio_id =1216
Now my question is how can I put the "and field=value" next to the left join in GORM?
You can use the WITH clause to achive this:
left join i3.analisys a3 WITH a3.something = :someValue
See also: current Hibernate user guide: HQL explicit join
For the below left outer join, my Java application sometimes receives a fetch out of sequence error:
"JDBC error reported: (SQLState = HY010) - java.sql.SQLException: [tibcosoftwareinc][Oracle JDBC Driver][Oracle]ORA-01002: fetch out of sequence "
After cycling the Oracle server, the issue seems to go away for a little while, but is back only days later. For every 100 time this query runs, it might produce 20 fetch out of sequence errors. I haven't been able to reproduce it manual, like by running the query from SQL Developer.
I'm not sure what the issue is because the application isn't updating or inserting into these tables. The query runs only after the table is populated, and only one instance of the application runs, sequentially. I'm also not using any PL/SQL. Everything I read about this error results from select-into statements and misuse of cursors. I'm not using either.
Does anyone have an idea what might be wrong here?
Thanks
select r.report_key, r.total, r.custom11, r.custom12, r.C_DATE, r.ORG_UNIT3, sum(j.journal_amount), j.ACCOUNT_CODE,
j.PAYER_NAME, re.posted_amount, re.ENTRY_ID, re.custom39, re.custom40, av.POSTED_AMT, av.TAX_AMT,
e.FOREIGN_OR_DOMESTIC, em.EMP_ID, r.custom9, re.description
from report r
left outer join journal j on r.REPORT_KEY = j.REPORT_KEY and r.SEQUENCENUMBER = j.SEQUENCENUMBER
left outer join report_entry re on r.REPORT_KEY = re.REPORT_KEY and r.SEQUENCENUMBER = re.SEQUENCENUMBER
left outer join ENTRY_LOCATION e on r.REPORT_KEY = e.REPORT_KEY and r.SEQUENCENUMBER = e.SEQUENCENUMBER
left outer join EMPLOYEE em on r.REPORT_KEY = em.REPORT_KEY and r.SEQUENCENUMBER = em.SEQUENCENUMBER
left outer join VAT_TAX av on r.REPORT_KEY = av.REPORT_KEY and r.SEQUENCENUMBER = av.SEQUENCENUMBER
where r.batchid = ? and r.report_key = ? and j.ACCOUNT_CODE != 'CASHADV'
group by r.report_key, r.total, r.custom11, r.custom12, r.C_DATE, r.ORG_UNIT3, j.ACCOUNT_CODE,
j.PAYER_NAME, re.posted_amount, re.ENTRY_ID, re.custom39, re.custom40, av.POSTED_AMT, av.TAX_AMT,
e.FOREIGN_OR_DOMESTIC, em.EMP_ID, r.custom9, re.description
I have a Set of columns and Tables, in respective drop downs, I am working on a Code to generate a dynamic SQL based on the Table-Column selection
It's working in case of simple Select statements but in the case of Multiple Joins, I am trying to figure out a Syntax for handlin Right and Left Joins.
Please help..this is the Error for SQL Syntax
1)
(Select dbo.Employee.Dept_ID,dbo.Employee.Emp_ID,dbo.Employee.Emp_Name,dbo.Employee_DataVal.DeptNo,
dbo.Employee_DataVal.EmpName,dbo.Employee_DataVal.EmpNo,dbo.Employee_DataVal.Salary,dbo.Emp_Sal.Emp_ID,dbo.Emp_Sal.Salary
FROM Employee
INNER JOIN Employee_DataVal
ON Employee.Dept_ID = Employee_DataVal.DeptNo
OR Employee_DataVal.EmpName = Employee.Emp_Name)
LEFT JOIN Emp_Sal
ON Employee.Emp_ID = Emp_Sal.Emp_ID
Incorrect syntax near the keyword 'LEFT'.
2)Select dbo.Employee.Dept_ID,dbo.Employee.Emp_ID,
dbo.Employee.Emp_Name,dbo.Employee_DataVal.DeptNo,
dbo.Employee_DataVal.EmpName,dbo.Employee_DataVal.EmpNo
,dbo.Emp_Sal.Emp_ID,dbo.Emp_Sal.Salary
FROM Employee INNER JOIN Employee_DataVal
ON Employee.Emp_ID = Employee_DataVal.EmpNo
AND Employee.Dept_ID = Employee_DataVal.DeptNo
LEFT JOIN Employee
ON Employee_DataVal.EmpName = Employee.Emp_Name
The objects "Employee" and "Employee" in the FROM clause have the same exposed names. Use correlation names to distinguish them.
PS: Running this sql on SQL server
This is a common problem when working with complex dynamic SQL strings on a string basis - the correct handling of the SQL syntax in its string form is difficult, and it is easy to create SQL injection vulnerabilities as well.
SQL builder APIs like jOOQ and others are very well suited for this task. I'm not sure what exactly the problem was in your case, but let's just assume that the last LEFT JOIN is optional in your query. You could write a query like this:
List<Field<?>> c = new ArrayList<>(Arrays.asList(
EMPLOYEE.DEPT_ID,
EMPLOYEE.EMP_ID,
EMPLOYEE.EMP_NAME,
EMPLOYEE_DATAVAL.DEPTNO,
EMPLOYEE_DATAVAL.EMPNAME,
EMPLOYEE_DATAVAL.EMPNO,
EMPLOYEE_DATAVAL.SALARY
));
Table<?> t = EMPLOYEE
.join(EMPLOYEE_DATAVAL)
.on(EMPLOYEE.DEPT_ID.eq(EMPLOYEE_DATAVAL.DEPTNO)
.or(EMPLOYEE_DATAVAL.EMPNAME.eq(EMPLOYEE.EMP_NAME));
if (someCondition) {
t = t.leftJoin(EMP_SAL).on(EMPLOYEE.EMP_ID.eq(EMP_SAL.EMP_ID));
c.addAll(Arrays.asList(
EMP_SAL.EMP_ID,
EMP_SAL.SALARY
));
}
Result<?> result =
ctx.select(c)
.from(t)
.fetch();
Speaking directly to the syntax errors:
The parentheses in this statement are invalid. Removing them will solve the problem.
The table Employee is used twice in the FROM clause. You must alias the tables for this to work.
Select dbo.Employee.Dept_ID,dbo.Employee.Emp_ID,
dbo.Employee.Emp_Name,dbo.Employee_DataVal.DeptNo,
dbo.Employee_DataVal.EmpName,dbo.Employee_DataVal.EmpNo
,dbo.Emp_Sal.Emp_ID,dbo.Emp_Sal.Salary
FROM Employee e1 INNER JOIN Employee_DataVal
ON e1.Emp_ID = Employee_DataVal.EmpNo
AND e1.Dept_ID = Employee_DataVal.DeptNo
LEFT JOIN Employee e2
ON Employee_DataVal.EmpName = e2.Emp_Name
Speaking to your broader question, the concept of a generic SQL query generator is quite common and has had several implementation. You won't find full implementation guidance in a forum such as this.
Cheers!
You are using LEFT Join same as the Self join. which is actually creating the problem.
In first case error is coming because of the wrong ) in wrong place as pointed below; Which making the end of query and so LEFT JOIN throwing an error. the ) must be at end of the query.
FROM Employee
INNER JOIN Employee_DataVal
ON Employee.Dept_ID = Employee_DataVal.DeptNo
OR Employee_DataVal.EmpName = Employee.Emp_Name ) <--Here
LEFT JOIN Emp_Sal
In second case, you are trying to do a self join to the same table in that case as the error already suggested you, you need to use correlation names like
FROM Employee emp1 <-- Here used a table alias emp1
INNER JOIN Employee_DataVal ed
ON emp1.Emp_ID = ed.EmpNo
AND emp.Dept_ID = ed.DeptNo
LEFT JOIN Employee emp2 <-- Here used a different table alias emp2
ON ed.EmpName = emp2.Emp_Name
Moreover, the LEFT JOIN Employee won't make any sense here and which can simply be modified to below code
FROM Employee emp1
INNER JOIN Employee_DataVal ed
ON emp1.Emp_ID = ed.EmpNo
AND emp.Dept_ID = ed.DeptNo
AND emp.Emp_Name = ed.EmpName <-- here by adding another join condition
I'm getting the following exception when I try to run my HQL query:
java.util.concurrent.ExecutionException: javax.ejb.EJBException:
java.lang.IllegalArgumentException: org.hibernate.QueryException: query specified join
fetching, but the owner of the fetched association was not present in the select list
And here is the query I'm running:
SELECT new com.airit.propworks.dto.CompanyContactReportDTO(comp, compStatus.statusDesc)
FROM CoCompany as comp
LEFT JOIN FETCH comp.coCompanyCategoriesCompanyNumbers as compCat
LEFT JOIN FETCH comp.coContactCompanyNumbers as compCont
LEFT JOIN FETCH comp.coOperatingNamesCompanyNumbers
LEFT JOIN compCat.categoryFunctionCoCategoryList as compFcn
LEFT JOIN FETCH compCont.coContactDocumentssCompositeFK1 as contDoc
LEFT JOIN FETCH compCont.coContactJobssCompositeFK1 as contJob
LEFT JOIN FETCH compCont.coPhoneNumberssCompositeFK1
LEFT JOIN FETCH contDoc.documentTypeCoDocumentTypes as docTypes
LEFT JOIN FETCH contJob.contactFunctionCoContactFunctions as contFcn
LEFT JOIN comp.companyStatusCoCompanyStatuses as compStatus --this was added by me
WHERE comp.companyNumber = ? ORDER BY comp.companyName
The line second to the last was added by me and the constructor was added by me. It wasn't until I added those lines that I started getting the exception.
As you can see the second to last line referring to comp.companyStatusCoCompanyStatuses is a join that returns a single CoCompanyStatuses object that I then try to get the statusDesc string from and pass to the constructor.
I'm not sure what is causing the exception I'm getting. Do you guys see anything?
There's an opened bug for using select new combined with join fetch.
Since the problem is with the added select new, you can separate the retrieval from constructing CompanyContactReportDTO.
I'm trying to translate a SQL quest into Hibernate criteria.
My quest is working in SQL :
select * from objective
left outer join conditionstate
on objective.conditionid = conditionstate.conditionid
and conditionstate.personid = XXXX
where objective.toto_id = YYYYY
The objective is not directly mapped to the condition_state, but into a condition.
objective --> condition <-- condition_state
I've tested something like :
final DetachedCriteria criteriaObjective =
DetachedCriteria.forClass(Objective.class);
criteriaObjective.createAlias("conditionState", "conditionState", Criteria.LEFT_JOIN);
without success..
It's hard to suggest something without seeing your actual mappings. Going by your explanation and assuming that both condition and conditionState are mapped as many-to-one, you'd write something like:
final DetachedCriteria criteriaObjective =
DetachedCriteria.forClass(Objective.class);
criteriaObjective
.createCriteria("condition", Criteria.LEFT_JOIN)
.createCriteria("conditionState", Criteria.LEFT_JOIN)
.add(Restrictions.eq("personid", "XXXX") );
criteriaObjective.add(Restrictions.eqProperty("toto_id", "YYYY") );
Note that the above is NOT equivalent to the SQL query you've provided because "personid" condition will be generated as part of "WHERE" clause. As far as I know it's impossible to do a left join with condition using Criteria API - you may need to use HQL instead which provides with keyword for that exact purpose:
select o from objective as o
left join o.condition as c
left join c.conditionState as cs
with cs.person_id = 'XXXX'
and o.toto_id = 'YYYY'