连接子句的聚合错误(选择MIN日期)

时间:2018-05-22 05:30:15

标签: sql sql-server tsql

我试图找出工作人员刚开始时的工资,为了做到这一点,我使用了一个连接功能,将一个表(EMPOS aka POSI)中的员工开始日期与员工的起薪日期相匹配。另一个表(EMSAL又称SAL),用于检索开始角色之日的工资金额。我想使用MIN函数来从EMPOS aka POSI中选择最低日期(开始日期),以及该日期是否与EMSAL aka SAL表中的工资日期和金额日期相匹配。

我遇到了以下错误

  
      
  • 聚合不能出现在ON子句中,除非它位于HAVING子句或选择列表中包含的子查询中,并且列中   被聚合是一个外部参考。
  •   

这是我的代码汇总 -

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 AND SAL.SMN_DATE 
= (SELECT MIN(POSI.POS_START) FROM EMPOS)

非常感谢您的协助。如果您有任何疑问或需要进一步的信息,请告诉我:))

干杯!

3 个答案:

答案 0 :(得分:0)

一种方法是使用子查询替换您对EMPOS表的连接,该子查询查找每个员工的早期日期。然后,使用该子查询限制到每个员工的第一条记录。

SELECT
    CS.Name, SAL.SalaryAmount
FROM CurrentStaff AS CS
LEFT JOIN
(
    SELECT DET_NUMBER, MIN(POS_START) AS first_start
    FROM EMPOS
    GROUP BY DET_NUMBER
) POSI
    ON CS.DET_NUMBERA = POSI.DET_NUMBER COLLATE
        SQL_Latin1_General_CP1_CI_AS AND CS.POS_STARTC = POSI.POS_START
LEFT JOIN EMSAL SAL
    ON CS.DET_NUMBERA = SAL.DET_NUMBER AND
       SAL.SMN_DATE = POSI.first_start COLLATE 
        SQL_Latin1_General_CP1_CI_AS;

答案 1 :(得分:0)

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 
    (SELECT * 
     FROM EMSAL 
     WHERE SMN_DATE = (SELECT MIN(POS_START) 
                       FROM EMPOS)
    ) SAL 
on CS.DET_NUMBERA = SAL.DET_NUMBER COLLATE SQL_Latin1_General_CP1_CI_AS 

答案 2 :(得分:0)

子查询中有错误的表别名:

SELECT CS.Name, SAL.SalaryAmount 
FROM CurrentStaff CS LEFT OUTER JOIN
     EMPOS 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 AND 
        SAL.SMN_DATE = (SELECT MIN(POSI2.POS_START) FROM EMPOS POSI2);

但是,我发现subqueries in the ON`条款难以理解,所以我将其写成:

SELECT CS.Name, SAL.SalaryAmount 
FROM CurrentStaff CS LEFT OUTER JOIN
     (SELECT POSI.*, MIN(POSI.POS_START) OVER () as MIN_POS_START
      FROM EMPOS POSI
     ) 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 AND 
        SAL.SMN_DATE = POSI.MIN_POS_START) ;

那就是说,我也很惊讶你希望整体最低,而不是每个员工的最低要求。所以,MIN()应该是:

MIN(POSI.POS_START) OVER (PARTITION BY POSI.DET_NUMBER)

同样,您的子查询应该有一个关联子句。