【问题标题】:Running total for payments to the issued invoices已开具发票的付款总计
【发布时间】:2020-12-09 12:02:38
【问题描述】:

我有以下表格:

create table Invoices (InvoiceID int, InvoiceDate date, Total money);
insert into Invoices (InvoiceID, InvoiceDate, Total) values
(1,'2020-11-01', 20),
(2,'2020-11-01', 14),
(3,'2020-11-02', 40),
(4,'2020-11-02', 35),
(5,'2020-11-03', 10),
(6,'2020-11-04', 63),
(7,'2020-11-04', 42);
   
create table Payments (InvoiceID int, PaymentDate date, Total money);
insert into Payments (InvoiceID, PaymentDate, Total) values
(5,'2020-11-07', 10),
(6,'2020-11-08', 63),
(4,'2020-11-09', 35),
(2,'2020-11-10', 14),
(7,'2020-11-11', 42),
(11,'2020-11-13', 20),
(13,'2020-11-14', 15);

要使用 SQL Server 2005 获得运行总计,我使用以下脚本:

with DateRange as
(
  select convert(date, '2020-11-01') as DateValue
  union all
  select dateadd(day, 1, dr.DateValue)
  from DateRange dr
  where dr.DateValue < '2020-11-30'
),
InvoicedTotal as
(
  select dr.DateValue,
         isnull(sum(i.Total), 0) as Invoiced
  from DateRange dr
  left join Invoices i
    on i.InvoiceDate = dr.DateValue
  group by dr.DateValue
),
PaidTotal as
(
  select dr.DateValue,
         isnull(sum(p.Total), 0) as Paid
  from DateRange dr
  left join Payments p
    on p.PaymentDate = dr.DateValue
  group by dr.DateValue
)
select convert(varchar(10), dr.DateValue, 102) as [YYYY.MM.DD],
       it1.Invoiced as [Invoiced],
       it3.Invoiced as [CumInvoiced],
       pt1.Paid as [Paid],
       pt3.Paid as [CumPaid],
       it3.Invoiced - pt3.Paid as [RunningTotal]
from DateRange dr
join InvoicedTotal it1
  on it1.DateValue = dr.DateValue
join PaidTotal pt1
  on pt1.DateValue = dr.DateValue
cross apply ( select sum(it2.Invoiced) as Invoiced
              from InvoicedTotal it2
              where it2.DateValue <= dr.DateValue ) it3
cross apply ( select sum(pt2.Paid) as Paid
              from PaidTotal pt2
              where pt2.DateValue <= dr.DateValue ) pt3
order by dr.DateValue;

如何在报告中仅显示在指定时间范围内已开具发票的付款?

【问题讨论】:

  • 这里指定的时间范围是2020-11-012020-11-30?所有样本数据均为 2020 年 11 月。因此将包括所有样本数据。只要DateRange CTE 没有更新,例如 12 月的新样本数据就不会成为计算的一部分。能否请您更新样本数据(如果需要)并提供目标时间范围和相应的预期结果?
  • 我已经修改了小提琴,看这里:dbfiddle.uk/…
  • 从 Payments 表中的数据可以看出,对于最后两条记录(InvoiceID:11 和 13),Invoices 表中没有任何记录,所以我希望将这两条排除在外报告计算值。
  • 想我明白了。我用小提琴网站上的信息更新了你的问题。 StackOverflow 问题不应依赖于仅在外部网站上可用的问题数据。

标签: sql-server-2005 cumulative-sum


【解决方案1】:
with DateRange as
(
  select convert(date, '2020-11-01') as DateValue
  union all
  select dateadd(day, 1, dr.DateValue)
  from DateRange dr
  where dr.DateValue < '2020-11-30'
),
InvoicedTotal as
(
  select dr.DateValue,
         isnull(sum(i.Total), 0) as Invoiced
  from DateRange dr
  left join Invoices i
    on i.InvoiceDate = dr.DateValue
  group by dr.DateValue
),
PaidTotal as
(
  select dr.DateValue,
         isnull(sum(case
                      when i.InvoiceDate between '2020-11-01' and '2020-11-30' -- check if matching invoice was found
                      then p.Total                 -- YES = include Total amount in sum
                      else 0                       -- NO  = exclude total amount from sum
                    end), 0) as Paid
  from DateRange dr
  left join Payments p
    on p.PaymentDate = dr.DateValue
  left join Invoices i
    on  i.InvoiceId = p.InvoiceId -- check for invoice related to payment
  group by dr.DateValue
)
select convert(varchar(10), dr.DateValue, 102) as [YYYY.MM.DD],
       it1.Invoiced as [Invoiced],
       it3.Invoiced as [CumInvoiced],
       pt1.Paid as [Paid],
       pt3.Paid as [CumPaid],
       it3.Invoiced - pt3.Paid as [RunningTotal]
from DateRange dr
join InvoicedTotal it1
  on it1.DateValue = dr.DateValue
join PaidTotal pt1
  on pt1.DateValue = dr.DateValue
cross apply ( select sum(it2.Invoiced) as Invoiced
              from InvoicedTotal it2
              where it2.DateValue <= dr.DateValue ) it3
cross apply ( select sum(pt2.Paid) as Paid
              from PaidTotal pt2
              where pt2.DateValue <= dr.DateValue ) pt3
order by dr.DateValue;

Fiddlemilo2011

【讨论】:

  • 否,报告中的值仍处于选中状态。我已经修改了提琴手,以便它从外部报告间隔插入发票。见这里:dbfiddle.uk/…
  • 查看此屏幕截图,其中包含不应存在的问题值:prnt.sc/vz4sqk
  • 我想我明白了。在您检查是否找到匹配发票的地方,我将其替换为 BETWEEN 运算符。见:dbfiddle.uk/…
  • 很高兴它为您工作!我已经更新了答案以匹配您的解决方案,并将其设为“社区 wiki”。有了足够的声誉,您应该能够自己更新它,以备将来更改时参考。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-03-24
  • 1970-01-01
  • 1970-01-01
  • 2021-12-28
  • 2015-10-09
  • 1970-01-01
  • 2013-07-25
相关资源
最近更新 更多