如何删除净额结算值(按余额为零值)Oracle SQL

8yparm6h  于 2023-10-16  发布在  Oracle
关注(0)|答案(2)|浏览(115)

我需要在Oracle SQL中解决这个问题,我有这个表:
| 平衡|账户|子帐户|值|
| --|--|--|--|
| 251 | 23000 | 230014 |-1000|
| 251 | 23001 | 230013 |一千个|
| 251 | 23002 | 230012 |- 一千|
| 250 | 22000 | 220014 | 1000 |
| 250 | 22001 | 220013 |五百|
| 250 | 22002 | 220012 |五百|
| 250 | 22011 | 220011 |-200|
| 250 | 22012 | 220010 |200|
最后,我只想要这个:
| 平衡|账户|子帐户|值|
| --|--|--|--|
| 251 | 23002 | 230012 |- 一千|
| 250 | 22000 | 220014 | 1000 |
| 250 | 22001 | 220013 |五百|
| 250 | 22002 | 220012 |五百|
我想通过余额删除净值,具有相同的金额,而不是总和(金额)。
你能帮帮我吗
谢谢你,

eulz3vhy

eulz3vhy1#

您可以使用解析函数为每个balance/value组合的行建立索引,然后计算具有相同balance/绝对value/索引的行对并排除这些行:

SELECT balance, account, subaccount, value
FROM   (
  SELECT t.*,
         COUNT(*) OVER (PARTITION BY balance, ABS(value), rn) AS cnt
  FROM   (
    SELECT t.*,
           ROW_NUMBER() OVER (
             PARTITION BY balance, value
             ORDER BY ROWNUM
           ) AS rn
    FROM   table_name t
  ) t
)
WHERE  cnt = 1;

其中,对于样本数据:

CREATE TABLE table_name (balance, account, subaccount, value) AS
SELECT 251, 23000, 230014, -1000 FROM DUAL UNION ALL
SELECT 251, 23001, 230013,  1000 FROM DUAL UNION ALL
SELECT 251, 23002, 230012, -1000 FROM DUAL UNION ALL
SELECT 250, 22000, 220014,  1000 FROM DUAL UNION ALL
SELECT 250, 22001, 220013,  -500 FROM DUAL UNION ALL
SELECT 250, 22002, 220012,  -500 FROM DUAL UNION ALL
SELECT 250, 22011, 220011,  -200 FROM DUAL UNION ALL
SELECT 250, 22012, 220010,   200 FROM DUAL;

输出:
| 平衡|账户|子帐户|值|
| --|--|--|--|
| 250 | 22001 | 220013 |五百|
| 250 | 22002 | 220012 |五百|
| 250 | 22000 | 220014 | 1000 |
| 251 | 23002 | 230012 |- 一千|
fiddle

lqfhib0f

lqfhib0f2#

with data(balance, account, subaccount, value) as (
    select 251, 23000, 230014, -1000 from dual union all
    select 251, 23001, 230013, 1000 from dual union all
    select 251, 23002, 230012, -1000 from dual union all
    select 250, 22000, 220014, 1000 from dual union all
    select 250, 22001, 220013, -500 from dual union all
    select 250, 22002, 220012, -500 from dual union all
    select 250, 22011, 220011, -200 from dual union all
    select 250, 22012, 220010, 200 from dual -- union all
),
rdata(balance, account, subaccount, value, rn) as (
    select 
        balance, account, subaccount, value,
        row_number() over(partition by balance order by account) as rn
    from data
),
ldata(balance, account, subaccount, value, rn, rnl) as (
    select d1.balance, d1.account, d1.subaccount, d1.value, d1.rn, d2.rn as rnl
    from rdata d1
    join rdata d2
        on d1.balance = d2.balance and d1.rn < d2.rn and d1.value = -d2.value
)
select balance, account, subaccount, value from rdata d
where not exists(
    select 1 from ldata d1
    where not exists(
        select 1 from ldata d2 where d1.balance = d2.balance
            and d1.rn = d2.rnl
    )
    and d.balance = d1.balance and (d.rn = d1.rn or d.rn = d1.rnl)
)
order by d.balance, d.rn
;

250 22000   220014  1000
250 22001   220013  -500
250 22002   220012  -500
251 23002   230012  -1000

相关问题