У меня есть запрос ниже, где я пытаюсь рассчитать процент на основе суммы G.MERCHANDISE_AMT
, деленной на сумму D.MERCHANDISE_AMT
. PO_ID
в этой таблице содержит 2 номера строк, а каждый номер строки имеет 2 распределения, всего 4 строки, и я получаю СУММУ D.MERCHANDISE_AMT
по всем 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 строк для одного и того же заказа, потому что распределение происходит по нескольким идентификаторам VOUCHER_ID. От PS_DISTRIB_LINE G
мне нужно получить СУММУ G.MERCHANDISE_AMT
из всех 10 строк (знаменатель), однако СУММА в числителе (ОТ PS_PO_LINE_DISTRIB D
) D.MERCHANDISE_AMT
должна основываться на 4 строках для этого PO_ID
.
Вот еще один способ взглянуть на это:
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'
.
Если я запрашиваю этот же PO_ID в PS_DISTRIB_LINE G
с помощью следующего запроса, это результаты:
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
Сумма MERCHANDISE_AMT
от PS_DISTRIB_LINE G
равна 56854,82, поэтому вычисление по выражению NULLIF((SUM(G.MERCHANDISE_AMT) / SUM(D.MERCHANDISE_AMT)),0) AS 'Threshold'
должно привести к следующему:
56845,82 / 79,400 = .7194
Однако, поскольку PS_DISTRIB_LINE
содержит больше строк, чем PS_PO_LINE_DISTRIB
(10 против 4 в этом примере) для того же PO_ID, вычисленная сумма на PS_PO_LINE_DISTRIB
становится искаженной (выше, чем должна быть)
Если я опрошу только эти две таблицы, используя их общие объединения, вы увидите, что проблема возникает, и SUM
из D.MERCHANDISE_AMT
(1-й столбец) будет неправильным:
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
Я разместил здесь скрипты CREATE TABLE в качестве дополнительной ссылки:
https://pastebin.com/rUbRCEj5
Что можно сделать, чтобы преодолеть это?
3/26 РЕДАКТИРОВАТЬ:
Я создал CTE с двумя отдельными внутренними запросами, которые были объединены в конечном выборе, однако я хочу сгруппировать по `(E.SETID + '_' + E.DEPTID) AS 'REQUESTOR', но это не группировка сюда. Нужно ли изменять внутренние запросы 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
3/27 РЕДАКТИРОВАТЬ:
Это изменения, которые я сделал до сих пор, и я думаю, что проблема возникает в последнем блоке операторов выбора (производных). Я прокомментировал 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 'PO_SUM_MERCH_AMT', 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_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_SETID, A.VENDOR_ID, A.BUYER_ID, D.DEPTID, E.SETID + '_' + E.DEPTID , H.ROLEUSER_SUPR )
, 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_AMT', G.BUSINESS_UNIT_PO --, G.SCHED_NBR, G.LINE_NBR, G.PO_DIST_LINE_NUM, G.VOUCHER_ID, G.VOUCHER_LINE_NUM, G.DISTRIB_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,
G.BUSINESS_UNIT_PO, H.ROLEUSER_SUPR )
Select REQUESTOR, BUSINESS_UNIT, PO_ID, PO_TYPE, PO_STATUS, PO_DT, VENDOR_SETID, VENDOR_ID, BUYER_ID, DEPTID, ROLEUSER_SUPR, NULLIF((SUM_MERCHA / SUM_MERCHB),0) AS 'Threshold' from
(
Select REQUESTOR, BUSINESS_UNIT, PO_ID, PO_TYPE, PO_STATUS, PO_DT, VENDOR_SETID, VENDOR_ID, BUYER_ID, DEPTID, ROLEUSER_SUPR, SUM(SUM_MERCHA) as SUM_MERCHA, SUM(SUM_MERCHB) as SUM_MERCHB from (
SELECT D.REQUESTOR, D.BUSINESS_UNIT, D.PO_ID, D.PO_TYPE, D.PO_STATUS, (CONVERT(CHAR(10),D.PO_DT,121)) as PO_DT, D.VENDOR_SETID, D.VENDOR_ID, D.BUYER_ID, D.DEPTID, D.ROLEUSER_SUPR, G.MERCHANDISE_AMT as SUM_MERCHA, D.MERCHANDISE_AMT as SUM_MERCHB
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.SCHED_NBR = D.SCHED_NBR AND G.LINE_NBR = D.LINE_NBR AND G.PO_DIST_LINE_NUM = D.DISTRIB_LINE_NUM)
--Group by D.REQUESTOR, D.BUSINESS_UNIT, D.PO_ID, D.PO_TYPE, D.PO_STATUS, PO_DT, D.VENDOR_SETID, D.VENDOR_ID, D.BUYER_ID, D.DEPTID, D.ROLEUSER_SUPR) E ) F