使用SQL根据日期计算总和的最佳方法

时间:2011-11-25 11:26:29

标签: sql date sum

我不知道根据SQL数据库中的日期维护总和的好方法。

带有两个表的数据库:

客户

  • clientID的
  • 名称
  • overdueAmount

发票

  • clientID的
  • invoiceID
  • 金额
  • 的dueDate
  • PAYMENTDATE

我需要提出一份客户名单,并按逾期金额(客户未支付的过期发票金额)进行订购。在大数据库中,无法实时计算它。

问题是在客户端上维护过期金额字段。即使客户发票上没有任何变化,此字段的数量也可能在午夜从一天变为另一天。

如果支付了发票,创建了新发票并且截止日期已过,截止日期已经过去且不是昨天,则此金额会发生变化...

我找到的唯一解决方案是通过总结尊重条件的发票,每天晚上重新计算每个客户的这个字段。但它在非常大的数据库上效率不高。

我认为这是一个常见问题,我想知道是否存在最佳做法?

2 个答案:

答案 0 :(得分:1)

首先,我想了解“非常大的数据库”是什么意思 - 大多数运行在体面硬件上的RDBMS系统应该能够实时计算这些数据,而不是数以亿计的发票。我是根据这里的经验说的。

其次,“最佳实践”是那些意味着很少的表达方式之一 - 它通常用于表达某人的意见,而不仅仅是一种意见。

我的意见中,到目前为止,最好的选择是动态计算。

如果您的数据库太大而您实际上无法做到这一点,我会考虑每晚批处理(如您所述)。每夜批量运行都很痛苦 - 特别是对于需要全天候可用的系统,但它们具有将所有逻辑保存在一个地方的好处。

如果您想避免每晚批次,可以使用触发器填充“unpaid_invoices”表。创建新发票记录时,触发器会将该发票复制到“unpaid_invoices”表中;当您使用付款更新发票,并且付款金额等于未付金额时,您将从unpaid_invoices表中删除。根据定义,unpaid_invoices表应远小于发票总数;在运行中计算给定客户的未付金额应该没问题。

然而,触发器是令人讨厌的,邪恶的东西,具有异乎寻常的失败模式,可以阻止毫无戒心的开发人员,所以只有在你手头有一个忍者SQL开发人员时才考虑这个。绝对要确保您有一个SQL查询来检查unpaid_invoices表的有效性,并理想地将其安排为常规任务。

答案 1 :(得分:1)

您应该阅读有关数据仓库的信息。它将帮助您解决此问题。它看起来与你刚刚说的相似

  

"我发现的唯一解决方案是每晚重新计算这个字段   通过总结尊重条件的发票,在每个客户。但   它在非常大的数据库上效率不高。"

但它有更多的东西。当你阅读它时,试着忘记规范化。它的主要目的是为了展示'数据,而不是'管理'数据。所以,一开始你会感到很奇怪,但如果你理解为什么我们需要数据仓库,那将非常有趣。

这本书可以是一个好的开始http://www.amazon.com/Data-Warehouse-Toolkit-Complete-Dimensional/dp/0471200247,经典之作。