JOIN子句使用MIN日期触发聚合错误的技术求助
解决JOIN ON子句中聚合函数报错的问题
你遇到的这个错误,核心原因是不能在JOIN的ON条件里直接使用引用外部表的聚合函数——你的子查询里用了MIN(POSI.POS_START),这里的POSI是外部JOIN语句里的表别名,相当于聚合函数引用了外部表的列,这就触发了SQL的语法限制。
结合你的需求(获取员工入职时的薪资),我给你两种修正方案,对应不同的业务场景:
场景1:每个员工匹配自己的最早入职日期对应的薪资
这应该是你真正的需求——每个员工对应自己入职那天的薪资。我们需要先通过子查询预计算出每个员工的最早入职日期,再用这个结果去关联薪资表:
SELECT CS.Name, SAL.SalaryAmount FROM CurrentStaff as CS -- 子查询先按员工编号分组,算出每个人的最早入职日期 LEFT OUTER JOIN ( SELECT DET_NUMBER, MIN(POS_START) AS EarliestHireDate FROM EMPOS GROUP BY DET_NUMBER ) AS POSI ON CS.DET_NUMBERA = POSI.DET_NUMBER COLLATE SQL_Latin1_General_CP1_CI_AS -- 用预计算的入职日期关联薪资表 LEFT OUTER JOIN EMSAL SAL ON CS.DET_NUMBERA = SAL.DET_NUMBER COLLATE SQL_Latin1_General_CP1_CI_AS AND SAL.SMN_DATE = POSI.EarliestHireDate
场景2:所有员工匹配全表最早入职日期对应的薪资
如果你确实是想让所有员工都匹配整个公司最早入职日期的薪资(这个场景比较少见),只需要把子查询改成独立的,不要引用外部的POSI别名即可:
SELECT CS.Name, SAL.SalaryAmount FROM CurrentStaff as CS LEFT OUTER JOIN EMPOS as POSI ON CS.DET_NUMBERA = POSI.DET_NUMBER COLLATE SQL_Latin1_General_CP1_CI_AS AND CS.POS_STARTC = POSI.POS_START LEFT OUTER JOIN EMSAL SAL ON CS.DET_NUMBERA = SAL.DET_NUMBER COLLATE SQL_Latin1_General_CP1_CI_AS -- 去掉POSI别名,子查询独立计算全表最小入职日期 AND SAL.SMN_DATE = (SELECT MIN(POS_START) FROM EMPOS)
为什么这样改能解决问题?
SQL语法规定,聚合函数(比如MIN)出现在ON子句时,要么是在不引用外部表的独立子查询里,要么是在子查询的SELECT列表/HAVING子句中且聚合的列是外部引用。我们通过预计算(场景1)或者改成独立子查询(场景2),都避开了直接在ON条件里引用外部表的聚合操作,自然就不会报错了。
内容的提问来源于stack exchange,提问作者NJ24031992
相关产品推荐
相关产品推荐

