SQL Server累积发票金额
我正试图解决一个法律记录保存的问题。如果在10天内在系统中输入发票冲销,我可以冲销发票。如果不重复计算反转,我如何实现这一点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
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\u chg
)选择费用chg
,并在发票日期进行额外分组,以防在同一天发生多笔费用。除此之外,它还添加了一个新列,其中包含上一个收费日期上一个发票日期
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