提问人:Mani 提问时间:11/13/2023 最后编辑:Mani 更新时间:11/14/2023 访问量:49
根据余额将释放分配给反向释放
Assign Releases to Reverse Release based on the balances
问:
我有两个表格,需要根据可用的余额(释放)分配金额。 这里的版本仅适用于 20 个,因此请根据可用性进行分配
释放
PID的 | relDate | 释放金额 |
---|---|---|
第1页 | 5 月 1 日 | 20 |
反向释放
PID的 | revRelDate | reverese发布 |
---|---|---|
第1页 | 5 月 5 日 | 15 |
第1页 | 5 月 6 日 | 8 |
所需输出
PID的 | relDate | revRelDate | 释放金额 | reverese发布 |
---|---|---|---|---|
第1页 | 5 月 1 日 | 5 月 5 日 | 20 | 15 |
第1页 | 5 月 1 日 | 5 月 6 日 | 20 | 5 |
尝试查询:
WITH RELEASE AS (
SELECT 'P1' PID, '2023-05-01' TRANSACTION_DATE, 23 RELEASE
FROM DUAL
) ,
REV_RELEASE AS (
SELECT 'P1' PID, '2023-05-05' TRANSACTION_DATE, 15 REV_RELEASE
FROM DUAL
UNION ALL
SELECT 'P1' PID, '2023-05-06' TRANSACTION_DATE, 8 REV_RELEASE
FROM DUAL)
SELECT *,CASE
WHEN RUNNING_TOTAL >= 0
THEN
CASE
WHEN LEAD(RUNNING_TOTAL, 1, 0) OVER (PARTITION BY PID ORDER BY TRANSACTION_DATE) >= 0
THEN REV_RELEASE
ELSE REV_RELEASE + RUNNING_TOTAL
END
ELSE 0
END
FROM (
SELECT a.RELEASE,b.*, SUM(RELEASE - REV_RELEASE) OVER (PARTITION BY a.PID ORDER BY b.TRANSACTION_DATE) AS RUNNING_TOTAL
FROM
RELEASE a FULL OUTER JOIN REV_RELEASE b
ON a.PID=b.PID
)
答:
1赞
MT0
11/13/2023
#1
您可以使用分析函数对金额进行合计,然后根据累计合计对表进行合计:JOIN
SELECT COALESCE(r.pid, rr.pid) AS pid,
r.transaction_date AS rel_date,
rr.transaction_date AS relRevDate,
r.release AS releaseAmount,
LEAST(
rr.rev_release,
rr.total_rev_release - r.total_release + r.release,
r.total_release - rr.total_rev_release + rr.rev_release
)
AS rev_release
FROM (
SELECT pid,
transaction_date,
release,
SUM(release)
OVER (PARTITION BY pid ORDER BY transaction_date, ROWNUM)
AS total_release
FROM RELEASE
) r
FULL OUTER JOIN (
SELECT pid,
transaction_date,
rev_release,
SUM(rev_release)
OVER (PARTITION BY pid ORDER BY transaction_date, ROWNUM)
AS total_rev_release
FROM REV_RELEASE
) rr
ON ( r.pid = rr.pid
AND r.total_release - r.release < rr.total_rev_release
AND r.total_release > rr.total_rev_release - rr.rev_release
)
其中,对于示例数据:
CREATE TABLE RELEASE (pid, transaction_date, release) AS
SELECT 'P1', DATE '2023-05-01', 5 FROM DUAL UNION ALL
SELECT 'P1', DATE '2023-05-03', 20 FROM DUAL UNION ALL
SELECT 'P1', DATE '2023-05-06', 4 FROM DUAL UNION ALL
SELECT 'P1', DATE '2023-05-07', 4 FROM DUAL;
CREATE TABLE REV_RELEASE (pid, transaction_date, rev_release) AS
SELECT 'P1', DATE '2023-05-05', 15 FROM DUAL UNION ALL
SELECT 'P1', DATE '2023-05-06', 8 FROM DUAL UNION ALL
SELECT 'P1', DATE '2023-05-07', 9 FROM DUAL;
输出:
PID的 | REL_DATE | RELREVDATE | 释放金额 | REV_RELEASE |
---|---|---|---|---|
小一 | 2023-05-01 00:00:00 | 2023-05-05 00:00:00 | 5 | 5 |
小一 | 2023-05-03 00:00:00 | 2023-05-05 00:00:00 | 20 | 10 |
小一 | 2023-05-03 00:00:00 | 2023-05-06 00:00:00 | 20 | 8 |
小一 | 2023-05-03 00:00:00 | 2023-05-07 00:00:00 | 20 | 2 |
小一 | 2023-05-06 00:00:00 | 2023-05-07 00:00:00 | 4 | 6 |
小一 | 2023-05-07 00:00:00 | 2023-05-07 00:00:00 | 4 | 3 |
评论
0赞
Mani
11/14/2023
@MT0- 如果同一 PID 的版本是多个,则无法正常工作。如果我在 fiddle 中更新发布表,然后运行相同的发布表,则发布没有正确拆分。-------------------------- CREATE TABLE RELEASE (pid, transaction_date, release) AS SELECT 'P1', DATE '2023-05-01', 5 FROM DUAL UNION SELECT 'P1', DATE '2023-05-03', 20 FROM DUAL
1赞
d r
11/13/2023
#2
您可以将分析函数 Sum() Over() 与 windowing 子句 (...之间的行 ...获取运行总数。但是,您需要嵌套的 Case 表达式来处理REV_RELEASE列的结果,因为表中可能rev_release行更多行......
WITH -- S a m p l e D a t a :
release AS
( Select 'P1' "PID", Date '2023-05-01' "TRANSACTION_DATE", 20 "RELEASE" From Dual
),
rev_release AS
( Select 'P1' "PID", Date '2023-05-05' "TRANSACTION_DATE", 15 "REV_RELEASE" From Dual Union All
Select 'P1' "PID", Date '2023-05-06' "TRANSACTION_DATE", 8 "REV_RELEASE" From Dual
)
-- M a i n S Q L :
Select r.PID, r.TRANSACTION_DATE "REL_DATE", rr.TRANSACTION_DATE "REV_REL_DATE",
r.RELEASE "REL_AMOUNT",
CASE WHEN
Case When Sum(rr.REV_RELEASE) Over(Partition By r.PID Order By r.PID, rr.TRANSACTION_DATE
Rows Between Unbounded Preceding And Current Row) > r.RELEASE
Then rr.REV_RELEASE - ( Sum(rr.REV_RELEASE) Over(Partition By r.PID Order By r.PID, rr.TRANSACTION_DATE
Rows Between Unbounded Preceding And Current Row) - r.RELEASE
)
Else rr.REV_RELEASE
End < 0 Then 0
ELSE
Case When Sum(rr.REV_RELEASE) Over(Partition By r.PID Order By r.PID, rr.TRANSACTION_DATE
Rows Between Unbounded Preceding And Current Row) > r.RELEASE
Then rr.REV_RELEASE - ( Sum(rr.REV_RELEASE) Over(Partition By r.PID Order By r.PID, rr.TRANSACTION_DATE
Rows Between Unbounded Preceding And Current Row) - r.RELEASE
)
Else rr.REV_RELEASE
End
END "REV_RELEASE"
From release r
Inner Join rev_release rr ON(rr.PID = r.PID)
/* R e s u l t :
PID REL_DATE REV_REL_DATE REL_AMOUNT REV_RELEASE
--- --------- ------------ ---------- -----------
P1 01-MAY-23 05-MAY-23 20 15
P1 01-MAY-23 06-MAY-23 20 5 */
...在示例数据中多一点行
WITH -- S a m p l e D a t a 2 :
release AS
( Select 'P1' "PID", Date '2023-05-01' "TRANSACTION_DATE", 20 "RELEASE" From Dual Union All
Select 'P2' "PID", Date '2023-05-01' "TRANSACTION_DATE", 20 "RELEASE" From Dual
),
rev_release AS
( Select 'P1' "PID", Date '2023-05-05' "TRANSACTION_DATE", 15 "REV_RELEASE" From Dual Union All
Select 'P1' "PID", Date '2023-05-06' "TRANSACTION_DATE", 8 "REV_RELEASE" From Dual Union All
Select 'P1' "PID", Date '2023-05-07' "TRANSACTION_DATE", 8 "REV_RELEASE" From Dual Union All
--
Select 'P2' "PID", Date '2023-05-05' "TRANSACTION_DATE", 15 "REV_RELEASE" From Dual Union All
Select 'P2' "PID", Date '2023-05-06' "TRANSACTION_DATE", 4 "REV_RELEASE" From Dual
)
/* R e s u l t 2 :
PID REL_DATE REV_REL_DATE REL_AMOUNT REV_RELEASE
--- --------- ------------ ---------- -----------
P1 01-MAY-23 05-MAY-23 20 15
P1 01-MAY-23 06-MAY-23 20 5
P1 01-MAY-23 07-MAY-23 20 0
P2 01-MAY-23 05-MAY-23 20 15
P2 01-MAY-23 06-MAY-23 20 4 */
...如果需要,可以筛选出 REV_RELEASE = 0 的行,然后对生成的数据集的其余部分执行任何操作。
此外,如果您在发布表中有行,而表中没有匹配的行rev_release并且您想显示发布表行,那么只需在主 sql 中将内部联接更改为左联接即可。
评论
rev_release