我在下面的查询中尝试根据G.MERCHANDISE_AMT
的总和除以D.MERCHANDISE_AMT
的总和来计算百分比。该表中的PO_ID
包含2个行号,每个行号具有2个分布,共4行,我得到D.MERCHANDISE_AMT
的SUM遍及所有4行。请注意,G.MERCHANDISE_AMT
是这两个表PS_PO_LINE_DISTRIB D
和PS_DISTRIB_LINE G
SELECT A.BUSINESS_UNIT, A.PO_ID, A.PO_TYPE, A.PO_STATUS, (CONVERT(CHAR(10),A.PO_DT,121)), A.VENDOR_ID,
A.BUYER_ID, D.DEPTID, SUM(G.MERCHANDISE_AMT) AS 'TOTAL_VCHR_AMT', NULLIF((SUM(G.MERCHANDISE_AMT) / SUM(D.MERCHANDISE_AMT)),0) AS 'Threshold' , E.SETID + '_' + E.DEPTID AS 'REQUESTOR', H.ROLEUSER_SUPR
FROM PS_PO_LINE_DISTRIB D
INNER JOIN PS_PO_LINE C ON D.BUSINESS_UNIT = C.BUSINESS_UNIT AND D.PO_ID = C.PO_ID AND C.LINE_NBR = D.LINE_NBR
INNER JOIN PS_PO_HDR A ON A.BUSINESS_UNIT = C.BUSINESS_UNIT AND A.PO_ID = C.PO_ID
INNER JOIN PS_DEPT_TBL E ON E.DEPTID = D.DEPTID AND E.SETID = D.BUSINESS_UNIT_GL
INNER JOIN PS_DISTRIB_LINE G ON G.PO_ID = D.PO_ID AND G.BUSINESS_UNIT_PO = D.BUSINESS_UNIT AND G.LINE_NBR = D.LINE_NBR AND G.SCHED_NBR = D.SCHED_NBR AND G.PO_DIST_LINE_NUM = D.DISTRIB_LINE_NUM
INNER JOIN PS_ROLEXLATOPR H ON H.ROLEUSER = E.SETID + '_' + E.DEPTID
WHERE
A.PO_TYPE IN ('AGR','BO')
AND A.PO_STATUS IN ('A','D','O')
AND D.PO_ID = 'J010000185'
AND D.BUSINESS_UNIT = '50000'
AND E.EFFDT = (SELECT MAX(A_ED.EFFDT) FROM PS_DEPT_TBL A_ED
WHERE E.SETID = A_ED.SETID
AND E.DEPTID = A_ED.DEPTID
AND A_ED.EFFDT <= SUBSTRING(CONVERT(CHAR,GETDATE(),121), 1, 10))
GROUP BY A.BUSINESS_UNIT,A.PO_ID, A.PO_TYPE, A.PO_STATUS, (CONVERT(CHAR(10),A.PO_DT,121)), A.VENDOR_ID, A.BUYER_ID, D.DEPTID, E.SETID + '_' + E.DEPTID, H.ROLEUSER_SUPR
HAVING (SUM(F.MERCHANDISE_AMT) / SUM(D.MERCHANDISE_AMT)) > .80
ORDER BY PO_ID
问题是由于PS_PO_LINE_DISTRIB D
的联接,PS_DISTRIB_LINE G
的数据每行重复两次。
PS_DISTRIB_LINE G
本身包含10个针对同一PO的行,因为分布是跨多个VOUCHER_ID的。我需要从PS_DISTRIB_LINE G
的所有10行中得到G.MERCHANDISE_AMT
的SUM(分母),但是分子上的SUM(FROM PS_PO_LINE_DISTRIB D
)D.MERCHANDISE_AMT
必须基于PO_ID
的4行中。
这里是另一种看待方式:
SELECT *
FROM PS_PO_LINE_DISTRIB D
WHERE PO_ID = 'J010000185'
AND BUSINESS_UNIT = '50000'
得出PO_ID 'J010000185'
的以下数据
BUSINESS_UNIT PO_ID LINE_NBR SCHED_NBR DST_ACCT_TYPE QTY_PO DISTRIB_LINE_NUM CURRENCY_CD MERCHANDISE_AMT
50000 J010000185 1 1 DST 0.6000 1 USD 39240.000
50000 J010000185 1 1 DST 0.4000 2 USD 26160.000
50000 J010000185 2 1 DST 0.5000 1 USD 7000.000
50000 J010000185 2 1 DST 0.5000 2 USD 7000.000
因此上述D.MERCHANDISE_AMT的总和为79,400(这应该是进入NULLIF((SUM(G.MERCHANDISE_AMT) / SUM(D.MERCHANDISE_AMT)),0) AS 'Threshold'
分母的金额。
如果通过以下查询在PS_DISTRIB_LINE G
中查询相同的PO_ID,则结果如下:
SELECT *
FROM PS_DISTRIB_LINE
WHERE PO_ID = 'J010000185'
AND BUSINESS_UNIT = '50000'
BUSINESS_UNIT PO_ID VOUCHER_ID VOUCHER_LINE_NUM DISTRIB_LINE_NUM BUSINESS_UNIT_GL MONETARY_AMOUNT
50000 J010000185 00026741 2 1 11000 9810.000
50000 J010000185 00026741 2 2 41000 6540.000
50000 J010000185 00026921 2 1 11000 1774.130
50000 J010000185 00026921 2 2 41000 1774.130
50000 J010000185 00026922 2 1 11000 9810.000
50000 J010000185 00026922 2 2 41000 6540.000
50000 J010000185 00033438 2 1 11000 2128.280
50000 J010000185 00033438 2 2 41000 2128.280
50000 J010000185 00033440 2 1 11000 9810.000
50000 J010000185 00033440 2 2 41000 6540.000
{{1}中MERCHANDISE_AMT
的总和为56854.82,因此对表达式PS_DISTRIB_LINE G
的计算应得出以下结果:
56845.82 / 79,400 = .7194
但是,对于相同的PO_ID,由于NULLIF((SUM(G.MERCHANDISE_AMT) / SUM(D.MERCHANDISE_AMT)),0) AS 'Threshold'
包含的行多于PS_DISTRIB_LINE
(在此示例中为10比4),因此PS_PO_LINE_DISTRIB
上的计算出的SUM变得偏斜(高于应有的值) )
如果仅使用这两个表使用它们的公共联接查询,您会看到问题的发生,PS_PO_LINE_DISTRIB
(第一列)的SUM
将是错误的:
D.MERCHANDISE_AMT
我在此处发布了CREATE TABLE脚本作为其他参考: https://pastebin.com/rUbRCEj5
该如何解决?
3/26编辑:
我创建了一个CTE,在最终选择中加入了2个独立的内部查询,但是我想将'(E.SETID +'_'+ E.DEPTID)分组为'REQUESTOR',但没有分组那样。我需要修改内部查询分组依据吗?
SELECT D.MERCHANDISE_AMT, G.MERCHANDISE_AMT, D.MERCHANDISE_AMT, G.MERCHANDISE_AMT, D.BUSINESS_UNIT, G.BUSINESS_UNIT, D.PO_ID, G.PO_ID, D.LINE_NBR, G.LINE_NBR, D.DISTRIB_LINE_NUM, G.DISTRIB_LINE_NUM
FROM PS_PO_LINE_DISTRIB D
INNER JOIN PS_DISTRIB_LINE G ON G.PO_ID = D.PO_ID AND G.BUSINESS_UNIT_PO = D.BUSINESS_UNIT AND G.LINE_NBR = D.LINE_NBR AND G.SCHED_NBR = D.SCHED_NBR AND G.PO_DIST_LINE_NUM = D.DISTRIB_LINE_NUM
WHERE D.PO_ID = 'J010000185'
AND D.BUSINESS_UNIT = '50000'
MERCHANDISE_AMT MERCHANDISE_AMT BUSINESS_UNIT BUSINESS_UNIT PO_ID PO_ID LINE_NBR LINE_NBR DISTRIB_LINE_NUM DISTRIB_LINE_NUM
39240.000 9810.000 50000 50000 J010000185 J010000185 1 1 1 1
39240.000 9810.000 50000 50000 J010000185 J010000185 1 1 1 1
39240.000 9810.000 50000 50000 J010000185 J010000185 1 1 1 1
26160.000 6540.000 50000 50000 J010000185 J010000185 1 1 2 2
26160.000 6540.000 50000 50000 J010000185 J010000185 1 1 2 2
26160.000 6540.000 50000 50000 J010000185 J010000185 1 1 2 2
7000.000 2128.280 50000 50000 J010000185 J010000185 2 2 1 1
7000.000 1774.130 50000 50000 J010000185 J010000185 2 2 2 2
7000.000 1774.130 50000 50000 J010000185 J010000185 2 2 1 1
7000.000 2128.280 50000 50000 J010000185 J010000185 2 2 2 2
3/27编辑:
这些是我到目前为止所做的更改,我认为问题出在select(派生)语句的最后一个块上。我注释掉了Group By,因为那里似乎并不需要它,但是我遇到了语法错误。我相信需要添加别名,但是我已经添加了这些别名,但仍然出现错误。
WITH CTE AS
(SELECT A.BUSINESS_UNIT, A.PO_ID, A.PO_TYPE, A.PO_STATUS, (CONVERT(CHAR(10),A.PO_DT,121)) AS 'PO_DT', A.VENDOR_SETID, A.VENDOR_ID, A.BUYER_ID, D.DEPTID, D.LINE_NBR, D.SCHED_NBR, D.DISTRIB_LINE_NUM,
SUM(D.MERCHANDISE_AMT) AS 'SUM_MERCH', E.SETID + '_' + E.DEPTID AS 'REQUESTOR', H.ROLEUSER_SUPR
FROM PS_PO_LINE_DISTRIB D
INNER JOIN PS_PO_LINE C ON D.BUSINESS_UNIT = C.BUSINESS_UNIT AND D.PO_ID = C.PO_ID AND C.LINE_NBR = D.LINE_NBR
INNER JOIN PS_PO_HDR A ON A.BUSINESS_UNIT = C.BUSINESS_UNIT AND A.PO_ID = C.PO_ID
INNER JOIN PS_DEPT_TBL E ON E.DEPTID = D.DEPTID AND E.SETID = D.BUSINESS_UNIT_GL
--LEFT OUTER JOIN PS_VOUCHER_LINE F ON F.PO_ID = D.PO_ID AND F.BUSINESS_UNIT_PO = D.BUSINESS_UNIT AND F.LINE_NBR = D.LINE_NBR AND F.SCHED_NBR = D.SCHED_NBR
INNER JOIN PS_ROLEXLATOPR H ON H.ROLEUSER = E.SETID + '_' + E.DEPTID
WHERE
A.PO_TYPE IN ('AGR','BO')
AND A.PO_STATUS IN ('A','D','O')
--AND D.MERCHANDISE_AMT <> 0.00
--AND Threshold > .80
AND D.PO_ID = 'J010000185'
AND D.BUSINESS_UNIT = '50000'
AND E.EFFDT = (SELECT MAX(A_ED.EFFDT) FROM PS_DEPT_TBL A_ED
WHERE E.SETID = A_ED.SETID
AND E.DEPTID = A_ED.DEPTID
AND A_ED.EFFDT <= SUBSTRING(CONVERT(CHAR,GETDATE(),121), 1, 10))
GROUP BY A.BUSINESS_UNIT,A.PO_ID, A.PO_TYPE, A.PO_STATUS, (CONVERT(CHAR(10),A.PO_DT,121)), A.VENDOR_SETID, A.VENDOR_ID, A.BUYER_ID, D.DEPTID, E.SETID + '_' + E.DEPTID , H.ROLEUSER_SUPR, D.LINE_NBR, D.SCHED_NBR, D.DISTRIB_LINE_NUM )
--HAVING (SUM(F.MERCHANDISE_AMT) / SUM(D.MERCHANDISE_AMT)) > .80 --, F.MERCHANDISE_AMT, D.MERCHANDISE_AMT --, C.LINE_NBR, D.QTY_PO, D.MERCHANDISE_AMT, D.DEPTID
, CTE2 AS (SELECT A.BUSINESS_UNIT, A.PO_ID, A.PO_TYPE, A.PO_STATUS, (CONVERT(CHAR(10),A.PO_DT,121)) AS 'PO_DT', A.VENDOR_SETID, A.VENDOR_ID, A.BUYER_ID, G.DEPTID, H.ROLEUSER_SUPR, SUM(G.MERCHANDISE_AMT) AS 'SUM_MERCH' , G.BUSINESS_UNIT_PO, G.LINE_NBR, G.SCHED_NBR, G.PO_DIST_LINE_NUM
FROM PS_DISTRIB_LINE G
INNER JOIN PS_PO_LINE C ON G.BUSINESS_UNIT = C.BUSINESS_UNIT AND G.PO_ID = C.PO_ID AND C.LINE_NBR = G.LINE_NBR
INNER JOIN PS_PO_HDR A ON A.BUSINESS_UNIT = C.BUSINESS_UNIT AND A.PO_ID = C.PO_ID
INNER JOIN PS_DEPT_TBL E ON E.DEPTID = G.DEPTID AND E.SETID = G.BUSINESS_UNIT_GL
INNER JOIN PS_ROLEXLATOPR H ON H.ROLEUSER = E.SETID + '_' + E.DEPTID
WHERE G.BUSINESS_UNIT = '50000'
AND G.PO_ID = 'J010000185'
AND E.EFFDT = (SELECT MAX(A_ED.EFFDT) FROM PS_DEPT_TBL A_ED
WHERE E.SETID = A_ED.SETID
AND E.DEPTID = A_ED.DEPTID
AND A_ED.EFFDT <= SUBSTRING(CONVERT(CHAR,GETDATE(),121), 1, 10))
GROUP BY A.BUSINESS_UNIT,A.PO_ID, A.PO_TYPE, A.PO_STATUS, (CONVERT(CHAR(10),A.PO_DT,121)), A.VENDOR_SETID, A.VENDOR_ID, A.BUYER_ID, G.DEPTID, H.ROLEUSER_SUPR,G.BUSINESS_UNIT_PO, G.LINE_NBR, G.SCHED_NBR, G.PO_DIST_LINE_NUM )--E.SETID + '_' + E.DEPTID )
SELECT DISTINCT D.BUSINESS_UNIT, D.PO_ID, D.PO_TYPE, D.PO_STATUS, (CONVERT(CHAR(10),D.PO_DT,121)), D.VENDOR_SETID, D.VENDOR_ID, D.BUYER_ID, D.DEPTID, D.ROLEUSER_SUPR, NULLIF((G.SUM_MERCH / D.SUM_MERCH),0) AS 'Threshold'
FROM CTE D
LEFT OUTER JOIN CTE2 G ON G.PO_ID = D.PO_ID AND G.BUSINESS_UNIT_PO = D.BUSINESS_UNIT AND G.LINE_NBR = D.LINE_NBR AND G.SCHED_NBR = D.SCHED_NBR AND G.PO_DIST_LINE_NUM = D.DISTRIB_LINE_NUM
GROUP BY D.BUSINESS_UNIT, D.PO_ID, D.PO_TYPE, D.PO_STATUS, (CONVERT(CHAR(10),D.PO_DT,121)), D.VENDOR_SETID, D.VENDOR_ID, D.BUYER_ID, D.DEPTID, D.ROLEUSER_SUPR