在一对多关系 DB2 中获得准确的边距
Getting accurate margins in one to many relationship DB2
TLORDER_ALL 是货物的摘要 table。它将向分配给该货件的所有承运人提供总应付账款,并且总应付账款记录在 INT_PAYABLE_AMT 字段中。
另一方面,ORDER_INTERLINER_ALL table 将列出分配给来自 TLORDER_ALL Table 的货物的每个承运人的应付款。 TLORDER_ALL 和 ORDER_INTERLINER_ALL 之间基本上是一对多的关系。 ORDER_INTERLINER_ALL table 中的 AMOUNT 字段中记录了支付给每个运营商的钱。如果发货后,Accounting 决定调整 money payable to a carrier,adjusted payable to a carrier 记录在ADJUSTED_AMOUNT in ORDER_INTERLINER_ALL table.If no adjustment, then ADJUSTED_AMOUNT=AMOUNT.
请注意,分配给一批货件的每个承运人可能使用不同的货币支付,这就是我使用 INT_PAYABLE_AMT *ADJUSTED_AMOUNT/AMOUNT 在会计调整后进行转换的原因,因为 INT_PAYABLE_AMT 以与 TLORDER_ALL table 中的 CHARGES(收入)字段相同的货币记录。
Long Store short,您的货物收入(CHARGES 字段)可能是美元,而多个承运人的货币是加元和/或美元。总应付 (INT_PAYABLE_AMT) 在转换后以与收入 (CHARGES) 字段相同的货币 (USD) 记录。最重要的是,您修改后的承运人应付账款(我们称之为 INT_PAYABLE_ADJUST_AMT)可能不同于 INT_PAYABLE_AMT。
这是我的摘要查询:
`SELECT
T.CUSTOMER,
T.CALLNAME,
COUNT(T.BILL_NUMBER) LOADS,
SUM(T.CHARGES+T.XCHARGES)TOTAL_REVENUE,
(SUM(T.CHARGES+T.XCHARGES)-SUM(T.INT_PAYABLE_AMT) *SUM(O.ADJUSTED_AMOUNT) /SUM(O.AMOUNT)) MARGIN
FROM TLORDER_ALL T
INNER JOIN ORDER_INTERLINER_ALL O ON O.DETAIL_LINE_ID=T.DETAIL_LINE_ID
WHERE T.INT_PAYABLE_AMT<>0
AND T.CHARGES+T.XCHARGES<>0
AND T.CUSTOMER='117990'
AND O.INTERFACE_STATUS='I'
AND O.AMOUNT<>0
GROUP BY T.CUSTOMER,T.CALLNAME`
这是我的详情查询
SELECT
T.DETAIL_LINE_ID,
T.BILL_NUMBER,
T.CUSTOMER,
T.CALLNAME,
(T.CHARGES+T.XCHARGES)TOTAL_REVENUE,
(T.CHARGES+T.XCHARGES-T.INT_PAYABLE_AMT *O.ADJUSTED_AMOUNT /O.AMOUNT) MARGIN,
T.INT_PAYABLE_AMT,
O.ADJUSTED_AMOUNT,
O.AMOUNT,
O.INTERFACE_STATUS
FROM TLORDER_ALL T
INNER JOIN ORDER_INTERLINER_ALL O ON O.DETAIL_LINE_ID=T.DETAIL_LINE_ID
WHERE T.INT_PAYABLE_AMT<>0
AND T.CHARGES+T.XCHARGES<>0
AND YEAR(T.DELIVER_BY)= YEAR(CURRENT DATE)
AND MONTH(T.DELIVER_BY)=MONTH(CURRENT DATE)-1
AND T.CUSTOMER='117990'
AND O.INTERFACE_STATUS='I'
AND O.AMOUNT<>0
我的问题是如何消除同一货件的多个条目,因为货件有多个承运人,并且能够在摘要和详细信息输出中获得准确的最终利润?
如果我们回顾一下详细信息图像,我想获得 5 条记录而不是 14 条记录,然后对所有承运人应付款项求和,使用 INT_PAYABLE_AMT *ADJUSTED_AMOUNT/AMOUNT 进行转换并从 [=60= 中减去] 对于这 5 条记录的每一行。应用相同的逻辑也可以在摘要输出中获得准确的结果。
谢谢。
好的,你的总结是正确的,制作CTE,然后逐步操作它
(请注意,我将在第一个 CTE 中保留所有行——这使得调试变得容易,注释掉之后的所有内容并添加 select 在每个步骤后验证值):
WITH Detail AS
(
SELECT
T.DETAIL_LINE_ID,
T.BILL_NUMBER,
T.CUSTOMER,
T.CALLNAME,
(T.CHARGES+T.XCHARGES)TOTAL_REVENUE,
(T.CHARGES+T.XCHARGES-T.INT_PAYABLE_AMT *O.ADJUSTED_AMOUNT /O.AMOUNT) MARGIN,
T.INT_PAYABLE_AMT,
O.ADJUSTED_AMOUNT,
O.AMOUNT,
O.INTERFACE_STATUS
FROM TLORDER_ALL T
INNER JOIN ORDER_INTERLINER_ALL O ON O.DETAIL_LINE_ID=T.DETAIL_LINE_ID
WHERE T.INT_PAYABLE_AMT<>0
AND T.CHARGES+T.XCHARGES<>0
AND YEAR(T.DELIVER_BY)= YEAR(CURRENT DATE)
AND MONTH(T.DELIVER_BY)=MONTH(CURRENT DATE)-1
AND T.CUSTOMER='117990'
AND O.INTERFACE_STATUS='I'
AND O.AMOUNT<>0
), C_COMBINE AS
(
-- Here we combine the amounts for each leg
SELECT
DETAIL_LINE_ID,
CUSTOMER,
-- Payable amt and customer are always the same, just pick one.
MAX(INT_PAYABLE_AMT) AS INT_PAYABLE_AMT,
SUM(ADJUSTED_AMOUNT) AS SUM_ADJUSTED_AMOUNT,
SUM(AMOUNT) AS SUM_AMOUNT
FROM Detail
GROUP BY DETAIL_LINE_ID, CUSTOMER
), ADJ_FOR_CURRENCY
(
SELECT
DETAIL_LINE_ID,
CUSTOMER,
INT_PAYABLE_AMT * (SUM_ADJUSTED_AMOUNT/SUM_AMOUNT) AS AMOUNT
FROM C_COMBINE
)
-- Now do what you want... roll up by customer?
SELECT
CUSTOMER,
SUM(AMOUNT) AS TOTAL_FOR_CUSTOMER
GROUP BY CUSTOMER
是的,这一切都可以用更少的行和更少的 CTE 来编写——通过将步骤合并为一个。但是之后就很难理解和编写了。这样一目了然,你可以添加评论和测试。例如,如果数字不正确,您将 select 更改为 SELECT * FROM C_COMBINE
并验证该步骤是否正常工作。
此外,如果您使用的是体面的优化服务器(并且 db2 是最好的或在 IMO 中名列前茅 - 虽然我在 IBM 工作,所以我可能有偏见)以这种方式使用 CTE 通常会允许编译器根据我的经验制定更快的执行计划。
祝你好运。
TLORDER_ALL 是货物的摘要 table。它将向分配给该货件的所有承运人提供总应付账款,并且总应付账款记录在 INT_PAYABLE_AMT 字段中。
另一方面,ORDER_INTERLINER_ALL table 将列出分配给来自 TLORDER_ALL Table 的货物的每个承运人的应付款。 TLORDER_ALL 和 ORDER_INTERLINER_ALL 之间基本上是一对多的关系。 ORDER_INTERLINER_ALL table 中的 AMOUNT 字段中记录了支付给每个运营商的钱。如果发货后,Accounting 决定调整 money payable to a carrier,adjusted payable to a carrier 记录在ADJUSTED_AMOUNT in ORDER_INTERLINER_ALL table.If no adjustment, then ADJUSTED_AMOUNT=AMOUNT.
请注意,分配给一批货件的每个承运人可能使用不同的货币支付,这就是我使用 INT_PAYABLE_AMT *ADJUSTED_AMOUNT/AMOUNT 在会计调整后进行转换的原因,因为 INT_PAYABLE_AMT 以与 TLORDER_ALL table 中的 CHARGES(收入)字段相同的货币记录。
Long Store short,您的货物收入(CHARGES 字段)可能是美元,而多个承运人的货币是加元和/或美元。总应付 (INT_PAYABLE_AMT) 在转换后以与收入 (CHARGES) 字段相同的货币 (USD) 记录。最重要的是,您修改后的承运人应付账款(我们称之为 INT_PAYABLE_ADJUST_AMT)可能不同于 INT_PAYABLE_AMT。
这是我的摘要查询:
`SELECT
T.CUSTOMER,
T.CALLNAME,
COUNT(T.BILL_NUMBER) LOADS,
SUM(T.CHARGES+T.XCHARGES)TOTAL_REVENUE,
(SUM(T.CHARGES+T.XCHARGES)-SUM(T.INT_PAYABLE_AMT) *SUM(O.ADJUSTED_AMOUNT) /SUM(O.AMOUNT)) MARGIN
FROM TLORDER_ALL T
INNER JOIN ORDER_INTERLINER_ALL O ON O.DETAIL_LINE_ID=T.DETAIL_LINE_ID
WHERE T.INT_PAYABLE_AMT<>0
AND T.CHARGES+T.XCHARGES<>0
AND T.CUSTOMER='117990'
AND O.INTERFACE_STATUS='I'
AND O.AMOUNT<>0
GROUP BY T.CUSTOMER,T.CALLNAME`
这是我的详情查询
SELECT
T.DETAIL_LINE_ID,
T.BILL_NUMBER,
T.CUSTOMER,
T.CALLNAME,
(T.CHARGES+T.XCHARGES)TOTAL_REVENUE,
(T.CHARGES+T.XCHARGES-T.INT_PAYABLE_AMT *O.ADJUSTED_AMOUNT /O.AMOUNT) MARGIN,
T.INT_PAYABLE_AMT,
O.ADJUSTED_AMOUNT,
O.AMOUNT,
O.INTERFACE_STATUS
FROM TLORDER_ALL T
INNER JOIN ORDER_INTERLINER_ALL O ON O.DETAIL_LINE_ID=T.DETAIL_LINE_ID
WHERE T.INT_PAYABLE_AMT<>0
AND T.CHARGES+T.XCHARGES<>0
AND YEAR(T.DELIVER_BY)= YEAR(CURRENT DATE)
AND MONTH(T.DELIVER_BY)=MONTH(CURRENT DATE)-1
AND T.CUSTOMER='117990'
AND O.INTERFACE_STATUS='I'
AND O.AMOUNT<>0
我的问题是如何消除同一货件的多个条目,因为货件有多个承运人,并且能够在摘要和详细信息输出中获得准确的最终利润?
如果我们回顾一下详细信息图像,我想获得 5 条记录而不是 14 条记录,然后对所有承运人应付款项求和,使用 INT_PAYABLE_AMT *ADJUSTED_AMOUNT/AMOUNT 进行转换并从 [=60= 中减去] 对于这 5 条记录的每一行。应用相同的逻辑也可以在摘要输出中获得准确的结果。
谢谢。
好的,你的总结是正确的,制作CTE,然后逐步操作它 (请注意,我将在第一个 CTE 中保留所有行——这使得调试变得容易,注释掉之后的所有内容并添加 select 在每个步骤后验证值):
WITH Detail AS
(
SELECT
T.DETAIL_LINE_ID,
T.BILL_NUMBER,
T.CUSTOMER,
T.CALLNAME,
(T.CHARGES+T.XCHARGES)TOTAL_REVENUE,
(T.CHARGES+T.XCHARGES-T.INT_PAYABLE_AMT *O.ADJUSTED_AMOUNT /O.AMOUNT) MARGIN,
T.INT_PAYABLE_AMT,
O.ADJUSTED_AMOUNT,
O.AMOUNT,
O.INTERFACE_STATUS
FROM TLORDER_ALL T
INNER JOIN ORDER_INTERLINER_ALL O ON O.DETAIL_LINE_ID=T.DETAIL_LINE_ID
WHERE T.INT_PAYABLE_AMT<>0
AND T.CHARGES+T.XCHARGES<>0
AND YEAR(T.DELIVER_BY)= YEAR(CURRENT DATE)
AND MONTH(T.DELIVER_BY)=MONTH(CURRENT DATE)-1
AND T.CUSTOMER='117990'
AND O.INTERFACE_STATUS='I'
AND O.AMOUNT<>0
), C_COMBINE AS
(
-- Here we combine the amounts for each leg
SELECT
DETAIL_LINE_ID,
CUSTOMER,
-- Payable amt and customer are always the same, just pick one.
MAX(INT_PAYABLE_AMT) AS INT_PAYABLE_AMT,
SUM(ADJUSTED_AMOUNT) AS SUM_ADJUSTED_AMOUNT,
SUM(AMOUNT) AS SUM_AMOUNT
FROM Detail
GROUP BY DETAIL_LINE_ID, CUSTOMER
), ADJ_FOR_CURRENCY
(
SELECT
DETAIL_LINE_ID,
CUSTOMER,
INT_PAYABLE_AMT * (SUM_ADJUSTED_AMOUNT/SUM_AMOUNT) AS AMOUNT
FROM C_COMBINE
)
-- Now do what you want... roll up by customer?
SELECT
CUSTOMER,
SUM(AMOUNT) AS TOTAL_FOR_CUSTOMER
GROUP BY CUSTOMER
是的,这一切都可以用更少的行和更少的 CTE 来编写——通过将步骤合并为一个。但是之后就很难理解和编写了。这样一目了然,你可以添加评论和测试。例如,如果数字不正确,您将 select 更改为 SELECT * FROM C_COMBINE
并验证该步骤是否正常工作。
此外,如果您使用的是体面的优化服务器(并且 db2 是最好的或在 IMO 中名列前茅 - 虽然我在 IBM 工作,所以我可能有偏见)以这种方式使用 CTE 通常会允许编译器根据我的经验制定更快的执行计划。
祝你好运。