SQL 求和条件

SQL Condition for sum

我有一个包含许多内部连接表的 sql 语句,正如您在下面看到的,我有许多条件 SUM 语句,这些总和给出了错误的(非常大的)数字,因为内部连接正在重复我的源 select 池中的值相同。我想知道是否有一种方法可以限制这些求和条件让我们对 EMPLID 说。代码是:

SELECT 
    A.EMPL_CTG, 
    B.DESCR AS PrName, 
    SUM(A.CURRENT_COMPRATE) AS SALARY_COST_BUDGET, 
    SUM(A.BUDGET_AMT) AS BUDGET_AMT, 
    SUM(A.BUDGET_AMT)*100/SUM(A.CURRENT_COMPRATE) AS MERIT_GOAL,
    SUM(C.FACTOR_XSALARY) AS X_Programp, 
    SUM(A.FACTOR_XSALARY) AS X_Program,
    COUNT(A.EMPLID) AS EMPL_CNT, 
    COUNT(D.EMPLID),
    SUM(CASE WHEN A.PROMOTION_SECTION = 'Y' THEN 1 ELSE 0 END) AS PRMCNT,
    SUM(CASE WHEN A.EXCEPT_IND = 'Y' THEN 1 ELSE 0 END) AS EXPCNT, 
    (SUM(CASE WHEN A.PROMOTION_SECTION = 'Y' THEN 1 ELSE 0 END)+SUM(CASE WHEN A.EXCEPT_IND = 'Y' THEN 1 ELSE 0 END))*100/(COUNT(A.EMPLID)) AS PEpercent 
FROM 
    EMP_DTL A INNER JOIN EMPL_CTG_L1 B ON A.EMPL_CTG = B.EMPL_CTG  
    INNER JOIN 
    ECM_PRYR_VW C ON A.EMPLID=C.EMPLID 
    INNER JOIN ECM_INELIG  D on D.EMPL_CTG=A.EMPL_CTG and D.YEAR=YEAR(getdate()) 
WHERE 
    A.YEAR=YEAR(getdate()) 
    AND B.EFF_STATUS='A' 
GROUP BY 
    A.EMPL_CTG, 
    B.DESCR 
ORDER BY B.DESCR

我已经尝试将 D.YEAR=YEAR(getdate()) 移动到 where 子句。任何帮助将不胜感激

您的数字非常大的可能原因可能是加入 A -> B、A -> C 和 A -> D 的笛卡尔积的结果,其中 tables C 和 D 似乎有多个记录。所以,举个例子……如果 A 有 10 条记录,而 C 有 10 条记录,每个 A 记录,你现在有 10 * 10 条记录……最后,将它加入 D table 和 10 条记录,你现在每个 "A" 有 10 * 10 * 10,因此你的答案很臃肿。

现在,如何解决。我已经根据连接列计算了您的 "C" 和 "D" tables 和 "Pre-Aggregated" 这些计数。这样,他们每个人将只有 1 条记录,总数已经在该级别计算,加入 A table 并且您失去了笛卡尔问题。

现在,对于 table B,它似乎只是一个查找 table,而且无论如何也只会是一个记录结果。

SELECT 
      A.EMPL_CTG, 
      B.DESCR AS PrName, 
      SUM(A.CURRENT_COMPRATE) AS SALARY_COST_BUDGET, 
      SUM(A.BUDGET_AMT) AS BUDGET_AMT, 
      SUM(A.BUDGET_AMT)*100/SUM(A.CURRENT_COMPRATE) AS MERIT_GOAL,
      PreAggC.X_Programp, 
      SUM(A.FACTOR_XSALARY) AS X_Program,
      COUNT(A.EMPLID) AS EMPL_CNT, 
      PreAggD.DCount,
      SUM(CASE WHEN A.PROMOTION_SECTION = 'Y' THEN 1 ELSE 0 END) AS PRMCNT,
      SUM(CASE WHEN A.EXCEPT_IND = 'Y' THEN 1 ELSE 0 END) AS EXPCNT, 
      ( SUM( CASE WHEN A.PROMOTION_SECTION = 'Y' THEN 1 ELSE 0 END
           + CASE WHEN A.EXCEPT_IND = 'Y' THEN 1 ELSE 0 END ) * 
           100 / COUNT(A.EMPLID) AS PEpercent 
   FROM 
      EMP_DTL A 
         INNER JOIN EMPL_CTG_L1 B 
            ON A.EMPL_CTG = B.EMPL_CTG  
           AND B.EFF_STATUS='A' 

         INNER JOIN ( select 
                            C.EMPLID,
                            SUM(C.FACTOR_XSALARY) AS X_Programp
                         from
                             ECM_PRYR_VW C
                         group by
                            C.EMPLID ) PreAggC
            ON A.EMPLID = PreAggC.EMPLID

         INNER JOIN ( select 
                            D.EMPLID,
                            COUNT(*) AS DCount
                         from
                             ECM_INELIG D 
                         where
                            D.Year = YEAR( getdate())
                         group by
                            D.EMPLID ) PreAggD
            ON A.EMPLID = PreAggD.EMPLID
   WHERE 
      A.YEAR=YEAR(getdate()) 
   GROUP BY 
      A.EMPL_CTG, 
      B.DESCR 
   ORDER BY 
      B.DESCR