求和的SQL条件

时间:2015-06-12 16:53:52

标签: sql sql-server inner-join

我有一个带有许多内部连接表的sql语句,如下所示,我有很多条件SUM语句,这些总和给了我错误的(非常大的)数字,因为内连接在我的源选择中重复相同的值池。我想知道有没有办法限制这些总和条件让我们说EMPLIDs。代码是:

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子句。任何帮助都会受到极大的赞赏

1 个答案:

答案 0 :(得分:0)

你的数字非常大的可能原因可能是由于加入A的笛卡尔积的结果 - > B,A - > C和A - > D表C和D似乎有多个记录。所以,只是示例...如果A有10条记录,而C对每条A记录都有10条记录,那么你现在有10 * 10条记录...最后,将它加入D表中有10条记录,你现在有10条*每个10 * 10" A",因此你臃肿的答案。

现在,如何解决。我已经把你的" C"和" D"表和"预聚合"这些计数基于连接列的基础。通过这种方式,他们每人只有1条记录,总计已在该级别计算,加入A表,您就会失去笛卡尔问题。

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

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