首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用SQL消除相等但相反的数据的最优雅的方法

使用SQL消除相等但相反的数据的最优雅的方法
EN

Stack Overflow用户
提问于 2020-01-21 22:10:24
回答 2查看 42关注 0票数 1

我有一组相对简单的数据,如下所示:

代码语言:javascript
复制
invoice_id    created_at     amount_in_cents         user_id
  22348       2019-11-07         550                31773927
  22349       2019-11-08        -550                31773927
  22498       2019-11-10        -3400               2389483
  22499       2019-11-10         3400               2389483
  22500       2019-11-11         18000              93842938

正如您所看到的,样本数据的前两行被归因于相同的user_id,但它们的值是相反的(加起来为0)。第3行和第4行也是如此。我想在30天内删除所有针对同一用户的反向发票,只留下第五行。

我可以用python来完成这个任务,但是它会大大扩展这个过程。有什么简单的方法可以用SQL来完成这个任务吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-01-21 22:27:54

您可以在关联子查询中使用not exists

代码语言:javascript
复制
select t.*
from mytable t
where not exists (
    select 1
    from mytable t1
    where 
        t1.user_id = t.user_id
        and greatest(t1.created_at, t.created_at) 
            <= least(t1.created_at, t.created_at) + interval '30 days'
        and t1.amount_in_cents = - t.amount_in_cents
)

not exists条件确保同一用户在30天内不存在其他记录,并且数量与之相反。

票数 1
EN

Stack Overflow用户

发布于 2020-01-21 22:42:15

我认为这个问题没有简单的解决办法。如果要删除所有匹配对,则可以枚举和删除:

代码语言:javascript
复制
select min(invoice_id), min(created_at), user_id, max(amount_in_cents) as amount_in_cents
from (select t.*,
             row_number() over (partition by user_id, amount_in_cents order by created_at) as seqnum
      from t
     ) t
group by abs(amount_in_cents), user_id, seqnum
having count(*) = 1;  -- only one "matching" amount

但是,30天的限制是很有挑战性的,我认为您可能需要一个递归的CTE。

考虑以下数据:

代码语言:javascript
复制
1    jan 1     500
1    jan 15    500
1    feb 1     -500
1    feb 10    -500

你想要什么结果?

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59849907

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档