【问题标题】:Database schema pattern for grouping transactions用于分组事务的数据库模式模式
【发布时间】:2021-03-28 22:42:18
【问题描述】:

我正在开发一个会计系统,其中有一种方法可以恢复错误进行的交易。 有些流程在生成交易的发票上运行。 一个流程可以为一张发票生成多笔交易。可以在一张发票上运行多个进程。

架构如下所示:

Transactions
========================================================
Id | InvoiceId | InvoiceProcessType | Amount  | CreatedOn
1     1            23                  10.00      Today
2     1            23                  13.00      Today
3     1            23                  17.00      Yesterday
4     1            23                  32.00      Yesterday 

现在 1 和 2 一起发生,3 和 4 一起发生,我想恢复后者 (3,4),将它们分组的可能解决方案是什么。

一种可能的解决方案是添加一个列ProcessCount,该列在每个进程中递增。 新架构如下所示。

Transactions
==============================================================================
Id | InvoiceId | InvoiceProcessType | Amount  | CreatedOn     | ProcessCount
1     1            23                  10.00      Today          1 
2     1            23                  13.00      Today          1 
3     1            23                  17.00      Yesterday      2
4     1            23                  32.00      Yesterday      2 

还有其他方法可以实现吗? TIA

【问题讨论】:

  • 你怎么知道“每个过程”是什么?
  • 我非常怀疑 CreatedOn 的“Today”之类的值是否有用。我猜你实际上存储了一个日期时间值而不是一个字符串。但是,如果不具体了解哪个进程创建了哪些行,您的目标是不可能的。如果没有一些严肃和有问题的假设,就没有其他选择。并且列名“ProcessCount”非常容易误导 IMO - 这里没有“计数”

标签: sql sql-server database-design


【解决方案1】:

如果您基于createdon 日期/时间值之间的任意时间范围进行批处理,则可以使用lag() 和累积总和。例如,如果两行在一个小时内属于同一批次,则:

select t.*,
       sum(case when prev_createdon > dateadd(hour, -1, createdon) then 0 else 1 end) over 
           (partition by invoiceid order by createdon, id) as processcount
from (select t.*,
             lag(createdon) over (partition by invoiceid order by createdon, id) as prev_createdon
      from transactions t
     ) t;

也就是说,您的处理似乎需要增强。每次代码运行时,都应该在某个表中插入一行(比如processes)。从该插入生成的 id 应该用于插入到transactions。这样,您就可以保留有关何时(以及谁和什么等)插入特定交易的信息。

【讨论】:

    【解决方案2】:

    您可以使用dense_rank来识别它,如下所示:

    select t.*,
           dense_rank() over (partition by InvoiceId  
                             order by CreatedOn desc) as ProcessCount
      from your_table t
    

    然后您可以根据您的要求还原(/删除),无需显式维护ProcessCount 列。可以根据上面的查询推导出来。

    【讨论】:

    • 一个ProcessType的所有事务的createdon不一样,相差几毫秒。
    • 然后在 createdon 上使用 trunc
    猜你喜欢
    • 2012-01-08
    • 2015-04-18
    • 1970-01-01
    • 2013-09-28
    • 1970-01-01
    • 1970-01-01
    • 2023-03-15
    • 2014-06-19
    • 2010-10-09
    相关资源
    最近更新 更多