You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

带max条件关联查询报错,如何获取各企业最新ContractType数据?

修正HQL查询以获取企业最新合同类型数据的方案

嗨,我来帮你解决这个查询报错的问题~你遇到的a column may not be outer-joined to a subquery错误,本质是HQL的语法限制:它不允许在LEFT JOIN的ON子句里嵌套子查询作为过滤条件。咱们换个思路,就能实现“获取每个企业对应其最新创建的合同类型”的需求。

方案一:HQL兼容写法(子查询预取最新时间)

我们可以先通过子查询找出每个福利周期(CompanyBenefitPeriods)下的最新合同创建时间,再通过“福利周期ID+最新时间”的组合来匹配对应的合同记录:

SELECT 
    c.companyNo, 
    cbp.companyBenefitNo, 
    cct.companyContractNo, 
    cct.createdOn
FROM Company c
LEFT JOIN c.companyBenefitPeriods cbp
LEFT JOIN CompanyContractType cct 
    ON cct.companyBenefitPeriod = cbp 
    AND (cbp.companyBenefitPeriodNo, cct.createdOn) IN (
        SELECT 
            cbp_inner.companyBenefitPeriodNo, 
            MAX(cct_inner.createdOn)
        FROM CompanyBenefitPeriods cbp_inner
        JOIN cbp_inner.companyContractType cct_inner
        GROUP BY cbp_inner.companyBenefitPeriodNo
    )

这个写法利用分组查询预获取每个福利周期的最新创建时间,再通过多列匹配的方式关联到对应的合同记录,避开了HQL的语法限制。

方案二:原生SQL窗口函数写法(高效简洁)

如果你的数据库支持窗口函数(比如MySQL 8+、PostgreSQL、SQL Server等),用ROW_NUMBER()窗口函数会更高效直观:

SELECT 
    c.CompanyNo,
    cbp.CompanyBenefitNo,
    cct.CompanyContractNo,
    cct.CreatedOn
FROM Company c
LEFT JOIN CompanyBenefitPeriods cbp 
    ON c.CompanyNo = cbp.CompanyNo
LEFT JOIN (
    SELECT 
        *,
        ROW_NUMBER() OVER (
            PARTITION BY CompanyBenefitNo 
            ORDER BY CreatedOn DESC
        ) AS rn
    FROM CompanyContractType
) cct 
    ON cbp.CompanyBenefitNo = cct.CompanyBenefitNo 
    AND cct.rn = 1
-- 如果你想排除没有合同记录的企业,可以加上下面的条件
-- WHERE cct.CompanyNo IS NOT NULL

这个逻辑是先给每个福利周期下的合同记录按创建时间倒序排号,取每个组里排号为1的(也就是最新的)记录,再和主表关联,完美匹配你的期望结果。

结果验证

用你提供的样本数据测试,两种方案都会返回:

CompanyNoCompanyBenefitNoCompanyContractNoCreatedOn
112'27-11-2019'
224'27-01-2020'

内容的提问来源于stack exchange,提问作者Hiệp Tuấn

火山引擎 最新活动