grails HQL with clause



由于前面的问题没有答案,我想再问一部分。

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

我收到的消息

with-clause referenced two different from-clause elements

本机SQL

left join contract cnt
    on agr.wgv_id = cnt.wgv_id
       and agr.date >= cnt.validFrom
       and agr.date < cnt.validTill

在上一个问题中,建议使用HQL和"with"子句。这有可能吗?建议?

{替换}

如果您希望捕获空记录,则只需要左联接,否则只需使用联接

from Agenda agr
    inner join agr.agenda a with a.employee.id = :employeeId
    left join agr.employer wgr
    left join wgr.contracts cnt
where agr.date >= :start
    and agr.date <= :end
    and ((agr.date >= cnt.validFrom and agr.date < cnt.validTill) or agr.employer is Null)

通缉

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.valifTill
    where agr.date >= :start
        and agr.date <= :end
from Agenda agr 
    inner join agr.agenda a
     left join agr.employer wgr
    left join wgr.contracts cnt 
 where (a.employee.id = :employeeId) and (agr.date >= cnt.validFrom and agr.datm < cnt.validTill)

如果您希望捕获空记录,则只需要左联接,否则只需使用联接

根据评论:

一个雇主有很多合同,但其中只有一份有效,具体取决于特定日期

在这种情况下,您可以使用exists子句来选择1行以匹配条件,不确定以下内容是否完全正确(即,是否需要cnt并需要额外的cnt(,但可能有用:

from Agenda agr 
        inner join agr.agenda a
         left join agr.employer wgr
        left join wgr.contracts cnt 
     where (a.employee.id = :employeeId) and 
     exists (select 1 from Contracts cnt1 where cnt1.id = cnt.id  and agr.date < cnt1.valifTill and agr.date >=cnt1.validFrom)

如果你不需要cnt 的任何回复,这可能会更切中要害

    from Agenda agr 
    inner join agr.agenda a
     left join agr.employer wgr
 where (a.employee.id = :employeeId) and 
 exists (select 1 from Contracts cnt1 where agr.date < cnt1.valifTill and agr.date >=cnt1.validFrom)

另一个测试:

尝试将agr比较值更改为当前传入的实际参数,以便更改agr.date>=cnt.validFrom和agr.date<cnt.valifTill to agr.date>=:开始和agr.date<:结束

这行得通吗?

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 >= :start and agr.date < :end)
    where (agr.date >= :start
        and agr.date <= :end)

更新3 2015年9月16日

几天前,这让我思考并尝试了一些新的方法来实现它。。它是基于一个完全不同的数据集,我已经没有了,但我发现了以下内容:

select new map (agr as agr, agr.date as lst)
from Agenda agr
            inner join agr.agenda a with a.employee.id = :employeeId
            left join agr.employer wgr
            left join wgr.contracts cnt with (lst >=cnt.validFrom and lst < cnt.valifTill)
        where (agr.date >= :start
            and agr.date <= :end)

我认为这是一个不承认lst的例外。这让我想到,虽然它在这个循环中,但它无法保持现有的关系。。(可能是休眠中的错误(

所以我最终做了:

select new map (agr as agr)
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 >=cnt.validFrom and agr < cnt.validTill)
        where (agr.date >= :start
            and agr.date <= :end)

这很奇怪,但请注意,作为议程的agr也包含相同的日期字段ValidFrom和ValidTill。我确实尝试了另一个dateField,它只在其中一个,而不是在另一个,而且它似乎不再工作了。我的测试没有试图取回任何数据,它更多的是关于hql语法的工作,在上一个例子中似乎可以工作。

我希望这能进一步澄清这个答案的评论中被掩盖的评论。

最新更新