仅最新快照中存在的员工ID的总和

时间:2019-07-17 09:33:50

标签: sql sql-server

我有一个数据库,其中每个月为我们公司工作的每位员工提供一个行。因此,如果员工A从2016年7月至今一直在我们公司工作,那么这个人大约有24行(她服役的每个月要排一行)。

我正在尝试总结当前每位员工在特定职能方面的经验。因此,如果员工A在销售部门工作了6个月,在市场营销部门工作了18个月,那么我会在指示职能的列中计算该员工具有销售或市场营销的行数。

我创建了一个似乎似乎在计算每个员工的工作经验的代码,但是它对数据进行了两次计算。它不以最新快照为起点。

SELECT A.EMPLOYEE_ID,
SUM(CASE WHEN A.FUNCTION_CODE ='CUS' THEN 1 ELSE 0 END) AS EXP_CUS,
SUM(CASE WHEN A.FUNCTION_CODE ='MKT' THEN 1 ELSE 0 END) AS EXP_MKT
FROM [dbname].[AGL_V_HRA_FE_R].[VW_HRA_EMPLOYEE_DETAIL] AS A INNER JOIN [dbname].[AGL_V_HRA_FE_R].[VW_HRA_EMPLOYEE_DETAIL] AS B ON A.EMPLOYEE_ID = B.EMPLOYEE_ID
WHERE B.WORKLEVEL_CODE > '1'
GROUP BY A.EMPLOYEE_ID

我希望雇员A的输出为EXP_CUS = 6且EXP_MKT =18。相反,两者的输出都更高,因为它是重复计算的行。当我添加行AND B.SNAPSHOT_DATE ='2019-06-30'时,输出正确。我不想每月手动调整代码,而是参考最新的快照日期。

添加 原始表格如下所示:

SNAPSHOT_DATE | EMPLOYEE_ID | FUNCTION_CODE
2019-06-30    | 000000001   | CUS
2019-06-30    | 000000002   | MKT
2019-05-31    | 000000001   | CUS
2019-05-31    | 000000002   | MKT
2019-04-30    | 000000001   | MKT
2019-04-30    | 000000002   | MKT

所需的输出将是

EMPLOYEE_ID   | EXP_CUS     | EXP_MKT
000000001     | 2           | 1
000000002     | 0           | 3

2 个答案:

答案 0 :(得分:1)

您可以使用PIVOT获得所需的结果,如下所示-

SELECT EMPLOYEE_ID,
ISNULL([CUS],0) AS [EXP_CUS],
ISNULL([MKT],0) AS [EXP_MKT]
FROM 
(
    SELECT EMPLOYEE_ID,FUNCTION_CODE,COUNT(SNAPSHOT_DATE)  T
    FROM your_table
    GROUP BY EMPLOYEE_ID,FUNCTION_CODE
)P
PIVOT(
    SUM(T)
    FOR FUNCTION_CODE IN ([CUS],[MKT])
)PVT

输出为-

EMPLOYEE_ID EXP_CUS EXP_MKT
000000001   2       1
000000002   0       3

答案 1 :(得分:1)

我不明白您为什么使用自我联接。这似乎可以满足您的要求:

SELECT ED.EMPLOYEE_ID,
       SUM(CASE WHEN ED.FUNCTION_CODE ='CUS' THEN 1 ELSE 0 END) AS EXP_CUS,
       SUM(CASE WHEN ED.FUNCTION_CODE ='MKT' THEN 1 ELSE 0 END) AS EXP_MKT
FROM [dbname].[AGL_V_HRA_FE_R].[VW_HRA_EMPLOYEE_DETAIL] ed 
WHERE ED.WORKLEVEL_CODE > '1'
GROUP BY ED.EMPLOYEE_ID;

如果只希望雇员具有最近的快照日期,则可以使用窗口功能:

SELECT ED.EMPLOYEE_ID,
       SUM(CASE WHEN ED.FUNCTION_CODE ='CUS' THEN 1 ELSE 0 END) AS EXP_CUS,
       SUM(CASE WHEN ED.FUNCTION_CODE ='MKT' THEN 1 ELSE 0 END) AS EXP_MKT
(SELECT ED.*,
        MAX(SNAPSHOT_DATE) OVER () as OVERALL_MAX_SNAPSHOT_DATE,
        MAX(SNAPSHOT_DATE) OVER (PARTITION BY EMPLOYEE_ID) as EMPLOYEE_MAX_SNAPSHOT_DATE            
 FROM [dbname].[AGL_V_HRA_FE_R].[VW_HRA_EMPLOYEE_DETAIL] ED
) ED
WHERE ED.WORKLEVEL_CODE > '1' AND
      EMPLOYEE_MAX_SNAPSHOT_DATE = OVERALL_MAX_SNAPSHOT_DATE
GROUP BY ED.EMPLOYEE_ID;