需要一些严重的脑力!我有一个问题,我试图从两个给定的日期范围计算价格过度收费。基本上我有一个发票行如下:
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日期。所以有一个月的时间,客户被超额收费作为第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;
}
}
}
}
}
}
提前致谢
答案 0 :(得分: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