【问题标题】:C# Comparing Date RangesC# 比较日期范围
【发布时间】:2012-07-20 14:04:54
【问题描述】:

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

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;




                            }


                        }

                    }

                }

            }


        }

提前致谢

【问题讨论】:

  • 请注意,这些是 DD/MM/YYYY 日期,美国开发者...
  • result 来自哪里?另一个 Linq to SQL 查询?
  • Yes 结果是一堆具有不同 BillID 和 accountId 的账单

标签: c# .net sql linq


【解决方案1】:

试试这个...

 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

【讨论】:

  • Msg 206, Level 16, State 2, Line 2 操作数类型冲突:日期与 int 不兼容
  • @user1401320 可以发一下你的数据表结构吗
  • OK 修复了它已将“billto-1”修改为 else Dateadd(day,-1,billedto) 但我没有从中得到正确的计算,我的数据库表如下:
  • 创建表 [dbo].[Bill]( [id] [int] IDENTITY(1,1) NOT NULL, [AccountID] [int] NOT NULL, [BillID] [int] NOT NULL , [BilledFrom] [date] NOT NULL, [BilledTo] [date] NOT NULL, [Price] [decimal](18, 2) NOT NULL, CONSTRAINT [PK_Bill] 主键集群
  • CREATE TABLE [dbo].[Pricing]( [id] [int] IDENTITY(1,1) NOT NULL, [AccountID] [int] NOT NULL, [EffectiveFrom] [date] NOT NULL , [EffectiveTo] [date] NULL, [Price] [decimal](18, 2) NOT NULL, CONSTRAINT [PK_Pricing] PRIMARY KEY CLUSTERED
猜你喜欢
  • 2010-09-13
  • 1970-01-01
  • 2015-06-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-29
  • 1970-01-01
相关资源
最近更新 更多