带有子句的 grails HQL

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
     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)

如果你想捕获空记录,你只需要左连接,否则只需使用连接

根据评论:

A employer has many contracts, but only one of them is valid depending at a given date

在这种情况下,您可以对 select 1 行执行一个 exists 子句以匹配条件,但不确定以下内容是否完全正确(即,如果以上所有内容都需要 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= :start 和 agr.date < :end

这个有用吗?

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)

2015 年 9 月 16 日更新 3

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

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 的异常。这让我想到,虽然它在这个 with 循环中,但它无法保持现有关系..(可能是休眠中的错误)

所以我最后做了:

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)

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

我希望在这个答案的评论中进一步清除低沉的评论。

{已替换}

如果你想捕获空记录,你只需要左连接,否则只需使用连接

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