来自同一个表的递归子目标值

时间:2015-08-07 07:39:04

标签: sql sql-server-2008

我有一张下面详细的表格

 **SNo    DOP           PaymentFor  RequiredFee AmountPaid**
 600    8/6/2015    AnnualFee   400         200
 601    8/6/2015    AnnualFee   400         200
 612    8/7/2015    IDCardFee   50          5
 613    8/7/2015    IDCardFee   50          4
 614    8/7/2015    IDCardFee   50          3
 615    8/7/2015    IDCardFee   50          2
 616    8/7/2015    IDCardFee   50          6

我想编写一个查询以返回上述详细信息,并在中间使用Balance再添一列,如下所示。最初余额将是必需的费用,然后在下次付款时将需要 - 特定付款的付费金额。

 S.No   DOP         PaymentFor  RequiredFee Balance AmountPaid
 600    8/6/2015    AnnualFee   400         400     200
 601    8/6/2015    AnnualFee   400         200     200
 612    8/7/2015    IDCardFee   50          50      5
 613    8/7/2015    IDCardFee   50          45      4
 614    8/7/2015    IDCardFee   50          41      3
 615    8/7/2015    IDCardFee   50          38      2
 616    8/7/2015    IDCardFee   50          36      6

2 个答案:

答案 0 :(得分:0)

您不应该真正存储使用不同值在不同行中支付的余额。这意味着您的行只是状态,并且没有真正反映当前支付的内容。

即。如果我要回去查看S.No = 600的记录,我只知道付款前余额为400,但是现在谁说它是400?

将余额存储在订单旁边并不太明智。

  1. 此方法仅表示您有一个客户或一个人支付购买
  2. 表的主键依赖于varchar PaymentFor(和S.No)。
  3. 如果您希望模型运行,请忽略我的帖子。

答案 1 :(得分:0)

  

此查询有效(SQL Fiddle):

; with fees(pOrder, SNo, PaymentFor, RequiredFee, AmountPaid) as (
    Select row_number() over(partition by PaymentFor Order By SNo), SNo, PaymentFor, RequiredFee, AmountPaid
    From Fee as f
), balance(Id, pOrder, SNo, PaymentFor, Balance, AmountPaid) as (
    Select 0, f.pOrder, SNo, PaymentFor, RequiredFee, AmountPaid From Fees as f Where pOrder = 1
    Union All
    Select id+1, f.pOrder, f.SNo, f.PaymentFor, b.Balance-b.AmountPaid, f.AmountPaid From Fees as f
    Inner Join balance as b On f.PaymentFor = b.PaymentFor and f.pOrder-1 = b.pOrder
)
select f.SNo, f.DOP, f.PaymentFor, f.RequiredFee, b.Balance, f.AmountPaid 
from balance as b
Inner Join fee as f On b.SNo = f.SNo
  

做什么:

  • 首次CTE(费用)确保每组PaymentFor的SNo没有差距
  • 第二次CTE(余额)进行递归计算
  • Last Select添加缺少的参数,这些参数在CTE中不需要也不会使用

请注意,如果您的桌子很大或很大,它将无法真正有效。(许多历史值)您可能需要考虑模型的某些更改。这不是存储此类数据的最佳方式。