0

需要一些严重的脑力!我有一个问题,我试图计算两个给定日期范围内的天数多收费用。基本上我有如下发票行:

BillID     AccountID     BilledFrom        BillTo      Price
 34         3456         10/10/2012       10/12/2012    86p 

然后我有一个定价矩阵,可以是:

AccountID      EffectiveFrom       EffectiveTo     Price
 3456          09/09/2009          10/11/2012      86p
 3456          11/11/2012          20/11/2012      56p
 3456          21/11/2012          10/12/2013      24p
 3456          11/12/2013           null           18p -- null never expires

目前,初始价格是在 BillFrom 日期介于 EffectiveFrom 和 EffectiveTo 日期之间并按天计费的情况下采用的。现在我想计算账单中的多收费用,因为您可以看到 BillTo 日期超过了 86p 行的 EffectiveTo 日期。因此,在 1 个月的时间里,客户在第 2 行被多收了费用,或者应该开始定价。我需要一个 SQL 或 C# 中的函数,这将产生:

OverchargeID    type      BillID       Reason       Days     Price
    1          Credit      34       PriceChange      10        36p       (86p-56p)
    2          Credit      34       PriceChange      19        64p       (86p-24p)

我将处理 56000 条记录,其中可能有多达 10 个价格范围。我有下面的代码在服务器端工作,但它根本不实用,大约需要 10 分钟。对此代码的任何解决方案或修改将不胜感激。

foreach (InvoiceOverchargePriceChange_SelectResult line in result) {

            //Get the invoiceLineRecord
            InvoiceLine invoiceLine = _dataContext.InvoiceLines.Where(m=>m.InvoiceLineID == line.InvoiceLineID).FirstOrDefault();


            // get the prices for each line
            List<Pricing_SelectResult> prices = ctrl.Select(line.AccountID, null, null, null, null)
                                                    .Where(m=>m.BillingMethodID == line.BillingMethodID)
                                                    .OrderByDescending(m=>m.EffectiveFrom).ToList();

            // if the price count is greater than 1 then need to check if overcharges occurred
            if (prices.Count > 1) {

                DateTime date = new DateTime();
                int days = 0;
                decimal charge = 0; ;
                for (int i = 0; i < prices.Count(); i++) {
                    days = 0;
                    charge = 0;

                    //if it goes in we found our price that we used
                    if (invoiceLine.BillFrom >= prices[i].EffectiveFrom && prices[i].EffectiveTo != null) {

                        date = invoiceLine.BillTo;
                        if (prices[i].EffectiveTo == null) break;
                        //check the Bill to date does not exceed the effective To date, if it does go in
                        while (date >= prices[i].EffectiveTo) {



                            if (date == invoiceLine.BillTo) {

                                //if its first go set the price
                                charge = prices.Where(m => date >= m.EffectiveFrom).FirstOrDefault().Price;


                            }

                            if (charge == prices.Where(m => date >= m.EffectiveFrom).FirstOrDefault().Price) {

                                //increment the days counter
                                days++;
                                date = date.AddDays(-1);

                            }
                            else {

                                //insert the days and price into db here...


                                //reset the days
                                days = 0;
                                charge = prices.Where(m => date >= m.EffectiveFrom).FirstOrDefault().Price;




                            }


                        }

                    }

                }

            }


        }

提前致谢

4

1 回答 1

0

试试这个...

 select 
      ROW_NUMBER() over (order by BillID, StartDate),
      case when (billprice>pricingprice) then 'Credit' else 'Debit' end,
      BillID,
      DATEDIFF(d, startdate,enddate)+1 as days,
      billprice-pricingprice
 from
 (
      select 
           BillID, 
           case when Effectivefrom>BilledFrom then Effectivefrom else BilledFrom end startdate, 
           case when isnull(effectiveto,GETDATE())<BillTo 
                then isnull(effectiveto,GETDATE()) else billto-1 end enddate,
           bill.price as billprice,
           pricing.price as pricingprice
      from pricing
     inner join bill
                on bill.accountid= pricing.accountid 
                and (billedfrom<isnull(effectiveto,getdate())) and (BillTo>Effectivefrom)
                and bill.price <> pricing.price 
 ) v
于 2012-07-20T15:01:02.273 回答