Need some help in converting a (complex) existing SQL statement.
1) I have multiple left joins each with multiple AND conditions, the AND conditions are now via restrictions in the generated WHERE clause, so the number of results are less than expected. (The join AND is not equal to a WHERE condition). Question How to add a additional AND in the left join? E.g:
left join cc c
on a.w_id = c.w_id
and a.date >= c.startdate
and a.date < c.enddate
2) I have several "case when .. as x" lines, How to implement this in grails criteria?
3) Two left joined tables, depending on a field value in the base table, the first or the second table should be joined/give rows.
The first three classes are:
class Appointment{
static mapping = {
id column: 'Id'
employer column: 'EMP_ID'
appDate column: 'Date'
class Employer {
static mapping = {
id column: 'EMP_ID'
name column: 'EMP_NAME'
}
static hasMany = [contracts: Contract]
class Contract {
static mapping = {
id column: 'CNT_ID'
employer column: 'EMP_ID'
validFrom column: 'CNT_STARTDATE'
validUntil column: 'CNT_ENDDATE'
specialContract column: 'SpecialContract'
}
static belongsTo = [employer: Employer]
The used criteria (extraction);
def appointments = Appointment.createCriteria().list {
createAlias('employer','emp', CriteriaSpecification.LEFT_JOIN)
createAlias('emp.contracts','cnt', CriteriaSpecification.LEFT_JOIN)
projections {
..
}
..
// normal existing where conditions
and {
ge('appDate', start.clearTime())
le('appDate', end.clearTime())
}
isNull('deleted')
// join conditions, now WHERE conditions, should be LEFT JOIN AND
or {
isNull('employer')
and {
eq('cnt.specialContract', true)
geProperty('appDate','cnt.validFrom')
ltProperty('appDate','cnt.validUntil')
..
}
and {
eq('cnt.specialContract', false)
geProperty('appDate','cnt.validFrom')
ltProperty('appDate','cnt.validUntil')
..
}
}
order ('date', 'asc')
}
One of the original sql joins;
left join contract cnt (nolock)
on app.emp_id = cnt.emp_id
and app.appdate >= cnt.cnt_validFrom
and app.appdate < cnt.cnt_validUntil
Update 2015-09-07
I have now switched to HQL because of the WITH clause, but it is still not working for me.
Native
inner join agenda a on a.id = agr.agendaid
left join contract cnt on agr.wgv_id = cnt.wgv_id and agr.date >= cnt.cnt_validfrom and agr.date < cnt.cnt_validtill
HQL
from Agenda agr inner join agr.agenda a with a.employee.id = :employeeId
left join agr.employer wgr
left join wgr.contracts cnt with agr.date >= cnt.validFrom and agr.date < cnt.ValidUntil
Error and generated SQL with-clause referenced two different from-clause elements [
select ..
from promaetis.Agenda agr
inner join agr.agenda a with a.employee.id = :employeeId
left join agr.employer wgr
left join wgr.contracts cnt with agr.date >= cnt.validFrom and agr.date < cnt.validUntil
where agr.date >= :start
..
Seems that the WITH clause only works correct with a combination of field and parameter, and not with field = field What is the correct syntax for the WITH AND AND clause?