SQL Server累积发票金额

SQL Server累积发票金额,sql,sql-server,Sql,Sql Server,我正试图解决一个法律记录保存的问题。如果在10天内在系统中输入发票冲销,我可以冲销发票。如果不重复计算反转,我如何实现这一点 IF OBJECT_iD('tempdb..#INV') IS NOT NULL DROP TABLE #INV CREATE TABLE #INV ( LEGAL_REC_ID varchar(8), INVOICE_DATE date, INVOICE_CATEGORY varchar(3), IN

我正试图解决一个法律记录保存的问题。如果在10天内在系统中输入发票冲销,我可以冲销发票。如果不重复计算反转,我如何实现这一点

IF OBJECT_iD('tempdb..#INV') IS NOT NULL 
        DROP TABLE #INV 

CREATE TABLE #INV 
(
     LEGAL_REC_ID varchar(8), 
     INVOICE_DATE date, 
     INVOICE_CATEGORY varchar(3), 
     INVOICE_AMOUNT decimal (18,2)
)

INSERT INTO #INV(LEGAL_REC_ID, INVOICE_DATE, INVOICE_CATEGORY, INVOICE_AMOUNT) VALUES(  'A','01/01/20','CHG','500')
INSERT INTO #INV(LEGAL_REC_ID, INVOICE_DATE, INVOICE_CATEGORY, INVOICE_AMOUNT) VALUES(  'A','01/02/20','CHG','250')
INSERT INTO #INV(LEGAL_REC_ID, INVOICE_DATE, INVOICE_CATEGORY, INVOICE_AMOUNT) VALUES(  'A','01/05/20','REV','-400')
INSERT INTO #INV(LEGAL_REC_ID, INVOICE_DATE, INVOICE_CATEGORY, INVOICE_AMOUNT) VALUES(  'A','01/15/20','REV','-300')
INSERT INTO #INV(LEGAL_REC_ID, INVOICE_DATE, INVOICE_CATEGORY, INVOICE_AMOUNT) VALUES(  'A','01/20/20','CHG','100')
INSERT INTO #INV(LEGAL_REC_ID, INVOICE_DATE, INVOICE_CATEGORY, INVOICE_AMOUNT) VALUES(  'A','01/21/20','REV','-500')
INSERT INTO #INV(LEGAL_REC_ID, INVOICE_DATE, INVOICE_CATEGORY, INVOICE_AMOUNT) VALUES(  'A','01/22/20','REV','-100')
INSERT INTO #INV(LEGAL_REC_ID, INVOICE_DATE, INVOICE_CATEGORY, INVOICE_AMOUNT) VALUES(  'A','01/23/20','REV','-700')

+--------------+--------------+------------------+----------------+
| LEGAL_REC_ID | INVOICE_DATE | INVOICE_CATEGORY | INVOICE_AMOUNT |
+--------------+--------------+------------------+----------------+
| A            | 2020-01-01   | CHG              |         500.00 |
| A            | 2020-01-02   | CHG              |         250.00 |
| A            | 2020-01-05   | REV              |        -400.00 |
| A            | 2020-01-15   | REV              |        -300.00 |
| A            | 2020-01-20   | CHG              |         100.00 |
| A            | 2020-01-21   | REV              |        -500.00 |
| A            | 2020-01-22   | REV              |        -100.00 |
| A            | 2020-01-23   | REV              |        -700.00 |
+--------------+--------------+------------------+----------------+
预期结果:

+--------------+--------------+------------------+----------------+---------+-------------------+
| LEGAL_REC_ID | INVOICE_DATE | INVOICE_CATEGORY | INVOICE_AMOUNT | NET_DUE | CUMULATIVE AMOUNT |
+--------------+--------------+------------------+----------------+---------+-------------------+
| A            | 1/1/2020     | CHG              |            500 |     100 |               100 |
| A            | 1/2/2020     | CHG              |            250 |     250 |               350 |
| A            | 1/20/2020    | CHG              |            100 |       0 |               350 |
+--------------+--------------+------------------+----------------+---------+-------------------+

下面的问题给出了你想要的,但我必须同意关于你问题的第二个评论:

1月21日、22日和23日的冲销超出了发票金额,发生了什么

让这些记录消失在稀薄的空气中是不对的,当然不是为了金融数据。。。我在
netdue
旁边添加了一个
netdue2
列来说明。此外,在本概述中,
2020-01-15
上的发票冲销完全丢失(您的样本数据中在接下来的10天内没有
CHG

也就是说:下面的解决方案使用多个公共表表达式(CTE)来隔离流程的每个步骤。请查看解决方案是如何分步骤构建的。因此,有很多分组,可能存在更有效的解决方案

  • 第一个CTE(
    CTE\u chg
    )选择费用
    chg
    ,并在发票日期进行额外分组,以防在同一天发生多笔费用。除此之外,它还添加了一个新列,其中包含上一个收费日期
    上一个发票日期
  • 第二个CTE(
    CTE\u rev
    )获取第一个CTE的输出,并将其与反向的
    rev
    连接起来。如果在接下来的10天内没有发生逆转(
    ir.INVOICE\u日期合并(dateadd(dd,10,c.PREV\u INVOICE\u DATE),c.INVOICE\u DATE)
    ),则左连接。其中的
    coalesce()
    解决了一个电荷可能没有先前电荷的事实(第一行的情况就是这样)。将适用的冲销总额加在费用上,即可得出到期金额
    净到期金额
  • 最后一步是计算到期金额的总金额,并给出累计金额
  • 解决方案

    with cte_chg as
    (
      select i.LEGAL_REC_ID,
             i.INVOICE_DATE,
             lag(i.INVOICE_DATE) over(partition by i.LEGAL_REC_ID order by i.INVOICE_DATE) as PREV_INVOICE_DATE,
             i.INVOICE_CATEGORY,
             sum(i.INVOICE_AMOUNT) as INVOICE_AMOUNT
      from #INV i
      where i.INVOICE_CATEGORY = 'CHG'
      group by i.LEGAL_REC_ID,
               i.INVOICE_DATE,
               i.INVOICE_CATEGORY
    ),
    cte_rev as
    (
      select c.LEGAL_REC_ID,
             c.INVOICE_DATE,
             c.INVOICE_CATEGORY,
             c.INVOICE_AMOUNT,
             case
               when c.INVOICE_AMOUNT + coalesce(sum(ir.INVOICE_AMOUNT), 0) > 0
               then c.INVOICE_AMOUNT + coalesce(sum(ir.INVOICE_AMOUNT), 0)
               else 0
             end NET_DUE,
             c.INVOICE_AMOUNT + coalesce(sum(ir.INVOICE_AMOUNT), 0) as NET_DUE2
      from cte_chg c
      left join #INV ir
        on  ir.LEGAL_REC_ID = c.LEGAL_REC_ID
        and ir.INVOICE_DATE <= dateadd(dd, 10, c.INVOICE_DATE)
        and ir.INVOICE_DATE >  coalesce(dateadd(dd, 10, c.PREV_INVOICE_DATE), c.INVOICE_DATE)
        and ir.INVOICE_CATEGORY = 'REV'
      group by c.LEGAL_REC_ID,
               c.INVOICE_DATE,
               c.INVOICE_CATEGORY,
               c.INVOICE_AMOUNT
    )
    select r.LEGAL_REC_ID,
           r.INVOICE_DATE,
           r.INVOICE_CATEGORY,
           r.INVOICE_AMOUNT,
           r.NET_DUE,
           sum(r.NET_DUE) over(order by r.INVOICE_DATE rows between unbounded preceding and current row) as CUMULATIVE_AMOUNT,
           r.NET_DUE2,
           sum(r.NET_DUE2) over(order by r.INVOICE_DATE rows between unbounded preceding and current row) as CUMULATIVE_AMOUNT2
    from cte_rev r
    group by r.LEGAL_REC_ID,
             r.INVOICE_DATE,
             r.INVOICE_CATEGORY,
             r.INVOICE_AMOUNT,
             r.NET_DUE,
             r.NET_DUE2;
    

    向我们展示您尝试过的代码。我认为您在问题中没有完全描述您的场景。例如,根据您提供的数据,当存在多个候选发票时,您如何确定要对哪个发票应用撤销?1月21日、22日和23日的冲销超过了发票金额,发生了什么?每天有多张发票?它需要某种主键。@shugs。我认为这是一个相当复杂的问题,我不完全理解。每个CHG是否只允许一次反转?为什么净金额不是负值?未包含的反转会发生什么变化?如果唯一可用的冲销金额大于费用金额,该怎么办?非常有用且有见地!我们遇到的问题是,有时两个发票费用一起被冲销。因此,如果2020年1月5日的冲销金额超过500美元(例如750美元),则解决方案不包含结转金额。非常感谢你!
    LEGAL_REC_ID INVOICE_DATE INVOICE_CATEGORY INVOICE_AMOUNT NET_DUE CUMULATIVE_AMOUNT NET_DUE2 CUMULATIVE_AMOUNT2
    ------------ ------------ ---------------- -------------- ------- ----------------- -------- ------------------
    A            2020-01-01   CHG              500.00         100.00  100.00              100.00   100.00
    A            2020-01-02   CHG              250.00         250.00  350.00              250.00   350.00
    A            2020-01-20   CHG              100.00           0.00  350.00            -1500.00 -1150.00