我可以在单个 SQL 查询中将金额分配给多方并四舍五入到 'primary' 方吗?
Can I divide an amount across multiple parties and round to the 'primary' party in a single SQL query?
我正在开发一个 oracle PL/SQL 流程,该流程将单个货币金额分配给特定组中的多个相关方。假设 'pGroupRef' 是一个输入参数,当前的实现首先指定一个 'primary' 参与方,然后将金额分配给所有次要方,如下所示:
INSERT INTO ActualValue
SELECT
...
pGroupRef AS GroupRef,
ROUND(Am.Amount * P.SplitPercentage / 100, 2) AS Amount,
...
FROM
Amount Am,
Party P
WHERE
Am.GroupRef = pGroupRef
AND P.GroupRef = Am.GroupRef
...
P.PrimaryInd = 0;
最后,它运行第二个过程以插入任何剩余的金额给主要方,即:
INSERT INTO ActualValue
SELECT
...
pGroupRef AS GroupRef,
Am.Amount - S.SecondaryAmounts,
FROM
Amount Am,
Party P,
(SELECT SUM(Amount) AS SecondaryAmounts FROM ActualValue WHERE GroupRef = pGroupRef) S
WHERE
Am.GroupRef = pGroupRef
AND P.GroupRef = Am.GroupRef
...
P.PrimaryInd = 1;
但是,这里的完整查询非常大,我通过添加子组使这个区域更加复杂,每个子组都有自己的主要成员,并且有可能被覆盖——因此如果我继续使用这个实现那么这将意味着很多重复的 SQL.
我想我总是可以在 运行 单个统一插入之前将正确的数量计算到数组中 - 但我觉得必须有一种优雅的数学方法来在单个 [=25] 中捕获此逻辑=]查询。
因此您可以使用分析函数来获取您要查找的内容。由于我不知道你的确切结构,这只是一个例子:
SELECT s.party_id, s.member_id,
s.portion + DECODE(s.prime, 1, s.total - SUM(s.portion) OVER (PARTITION BY s.party_id),0)
FROM (SELECT p.party_id, p.member_id,
ROUND(a.amt*(p.split/100), 2) AS PORTION,
a.amt AS TOTAL, p.prime
FROM party p
INNER JOIN amount a ON p.party_id = a.party_id) s
所以在查询中你有一个收集所需信息的子查询,然后外部查询将所有内容放在一起,只将余数应用于标记为质数的记录。
这里有一个 DBFiddle 展示了它是如何工作的 (LINK)
N.B.: 有趣的是,在 DBFiddle 的例子中,有 0.01 的超额支付,所以主要支付的实际上更少。
我正在开发一个 oracle PL/SQL 流程,该流程将单个货币金额分配给特定组中的多个相关方。假设 'pGroupRef' 是一个输入参数,当前的实现首先指定一个 'primary' 参与方,然后将金额分配给所有次要方,如下所示:
INSERT INTO ActualValue
SELECT
...
pGroupRef AS GroupRef,
ROUND(Am.Amount * P.SplitPercentage / 100, 2) AS Amount,
...
FROM
Amount Am,
Party P
WHERE
Am.GroupRef = pGroupRef
AND P.GroupRef = Am.GroupRef
...
P.PrimaryInd = 0;
最后,它运行第二个过程以插入任何剩余的金额给主要方,即:
INSERT INTO ActualValue
SELECT
...
pGroupRef AS GroupRef,
Am.Amount - S.SecondaryAmounts,
FROM
Amount Am,
Party P,
(SELECT SUM(Amount) AS SecondaryAmounts FROM ActualValue WHERE GroupRef = pGroupRef) S
WHERE
Am.GroupRef = pGroupRef
AND P.GroupRef = Am.GroupRef
...
P.PrimaryInd = 1;
但是,这里的完整查询非常大,我通过添加子组使这个区域更加复杂,每个子组都有自己的主要成员,并且有可能被覆盖——因此如果我继续使用这个实现那么这将意味着很多重复的 SQL.
我想我总是可以在 运行 单个统一插入之前将正确的数量计算到数组中 - 但我觉得必须有一种优雅的数学方法来在单个 [=25] 中捕获此逻辑=]查询。
因此您可以使用分析函数来获取您要查找的内容。由于我不知道你的确切结构,这只是一个例子:
SELECT s.party_id, s.member_id,
s.portion + DECODE(s.prime, 1, s.total - SUM(s.portion) OVER (PARTITION BY s.party_id),0)
FROM (SELECT p.party_id, p.member_id,
ROUND(a.amt*(p.split/100), 2) AS PORTION,
a.amt AS TOTAL, p.prime
FROM party p
INNER JOIN amount a ON p.party_id = a.party_id) s
所以在查询中你有一个收集所需信息的子查询,然后外部查询将所有内容放在一起,只将余数应用于标记为质数的记录。
这里有一个 DBFiddle 展示了它是如何工作的 (LINK)
N.B.: 有趣的是,在 DBFiddle 的例子中,有 0.01 的超额支付,所以主要支付的实际上更少。