繁体   English   中英

sql根据第一次出现的数据和条件排除行

[英]sql exclude rows based on first occurrence of data and conditions

我创建了一个数据集,其中包含 2 个客户的列:

Cust_No Transaction_date    amount  credit_debit    running_total   row_num
1       5/27/2022           800     D               -200            1
1       5/26/2022           300     D               600             2
1       5/22/2022           800     C               900             3
1       5/20/2022           100     C               100             4
                    
9       5/16/2022           500     D               -300            1
9       5/14/2022           300     D               200             2
9       5/6/2022            200     C               500             3 
9       5/5/2022            500     D               300             4
9       5/2/2022            300     D               800             5
9       5/2/2022            500     C               1100            6
9       5/1/2022            500     C               600             7
9       5/1/2022            100     C               100             8

我正在寻找的结果是:

Cust_No Transaction_date    amount  credit_debit    running_total   row_num
1       5/27/2022           800     D               -200            1
1       5/26/2022           300     D               600             2
1       5/22/2022           800     C               900             3

                    
9       5/16/2022           500     D               -300            1
9       5/14/2022           300     D               200             2
9       5/6/2022            200     C               500             3 
9       5/5/2022            500     D               300             4
9       5/2/2022            300     D               800             5
9       5/2/2022            500     C               1100            6

我根据每个客户的最新交易对数据集进行了排序。

我们记下最新的交易金额,并搜索第一次出现的相同金额的贷方 (C),并排除其后的其余行。 在上面的示例中:客户 9 的最近借记交易为 500,因此我们查找最近的贷记交易 500,并排除客户 9 之后的所有行。

目前取得的进展:

  1. 使用逻辑计算运行总数:
sum (case when credit_debit ='C' then amount else -1*amount end) over (partition by cust_no order by transaction_date desc ) as running_total

我还使用线索 1、2、3、4、5 获取了数据,但这效率不高,在找到与第一行相同金额的第一个信用编号之前,我可以有多行:

case when lead(amount, 1) over(partition by cust_no order by transaction_date desc) = amount then amount else null end as lead1

不确定这是用于哪个 dbms,但它需要在 postgres 中进行横向连接。

它搜索当 rn = 1 时识别的最新交易,然后将该金额与相同金额的较早信用交易相匹配,并使用该行的 rn 形成要返回的行号边界:

with CTE as (
    select
          Cust_No, Transaction_date, amount, credit_debit, running_total
        , row_number() over(partition by cust_no order by transaction_date DESC) as rn
    from mytable
    )
, RANGE as (
    select *
    from CTE
    left join lateral (
        select c.rn as ignore_after
        from CTE as c
        where CTE.Cust_No = c.Cust_No
            and CTE.amount = c.amount 
            and  c.credit_debit = 'C'
            and CTE.rn = 1
        order by c.rn ASC
        limit 1
        ) oa on true
    where CTE.rn = 1
    )
select 
     CTE.*
from CTE
inner join RANGE on CTE.rn between RANGE.rn and RANGE.ignore_after
                and CTE.cust_no = RANGE.cust_no
客户编号 | 交易日期 | 金额 | 贷记借记 |  running_total |  rn
 ------: |  :--------------- |  -----: |  :----------- |  ------------: |  -:
       1 |  2022-05-27 |  800 |  D |  -200 |  1
       1 |  2022-05-26 |  300 |  D |  600 |  2
       1 |  2022-05-22 |  800 |  C |  900 |  3
       9 |  2022-05-16 |  500 |  D |  -300 |  1
       9 |  2022-05-14 |  300 |  D |  200 |  2
       9 |  2022-05-06 |  200 |  C |  500 |  3
       9 |  2022-05-05 |  500 |  D |  300 |  4
       9 |  2022-05-02 |  300 |  D |  800 |  5
       9 |  2022-05-02 |  500 |  C |  1100 |  6

对于 postgres,请参见: db<>fiddle here

注意:对于“外部应用”示例,我还在以下小提琴中使用了 SQL Server,请参见: db<>fiddle here

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM