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
我有一个包含许多内部连接表的 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