我有一个数据库(MySQL),它保存了一些客户的成本记录(每个客户的项目成本不同)。任何给定的成本记录都有一个有效的日期范围(即,成本在给定的时间范围内有效)。以下是一些示例数据:
Customer ItemNumber EffectDate Counter Cost
ABC123 ITEM101 2011-12-01 0 $1.00
ABC123 ITEM101 2011-12-10 0 $1.20
ABC123 ITEM101 2011-12-10 1 $1.25
DEF456 ITEM101 2011-11-15 0 $1.10
DEF456 ITEM101 2011-12-01 0 $1.12
为了弄清楚这些数据,“计数器”变量是它被更改的次数(这是来自过时的会计平台),日期是成本的“开始日期”。因此,客户ABC123的ITEM101将在2011年12月1日和2011年12月8日的成本为1.00美元,但从12/10/2011开始,将是1.25美元(将是1.20美元,但柜台已经上涨 - 即费用现在是1.25美元)。我希望这是有道理的。
我要做的是将数据输出如下:
Customer ItemNumber EffectiveBegin EffectiveEnd Cost
ABC123 ITEM101 2011-12-01 2011-12-09 $1.00
ABC123 ITEM101 2011-12-10 2099-12-31 $1.25
DEF456 ITEM101 2011-11-15 2011-11-30 $1.10
DEF456 ITEM101 2011-12-01 2099-12-31 $1.12
12/31/2099只是“当前”的占位符日期。
任何帮助都会非常感激!!
答案 0 :(得分:0)
UNTESTED :(读作:我可能至少有一个逻辑错误和2-3个语法错误)
Areas where there might be problems:
1) B.effectiveDate-1 - Hoping B.EffectDate-1 when B.EffectDate is null
will retrun null so coalesce will return 12/31/2099.
2) '12/31/2099' may need to be cast to date data type.
3) Hoping mySQL supports date-1 to subtract 1 day.
4) Replace "TABLE" with your table name
它的作用:
1) Joins to self in order to get begin & End for Effective dates. Excludes same
date entries.
2) subtracts 1 from B.effectdate when customer item has multiple entries to
get "End"
3) Only joins records where customer, item match AND B.Counter is the MAX counter.
(Key if multiple entires)
4) Uses cost from B if exists, otherwise uses A.
没有进一步的麻烦:
Select A.Customer, A.ItemNumber, A.EffectDate as EffectiveBegin,
coalesce(B.effectDate-1,'12/31/2099') as EffectiveEnd,
coalesce(B.cost, A.cost) as Cost
FROM Table A
LEFT JOIN Table B
ON A.Customer=B.Customer
and A.ItemNumber = B.ItemNumber
and A.EffectDate < B.EffectDate
and B.Counter = (SELECT max(C.Counter)
FROM Table C
WHERE C.Customer = A.customer
and C.ItemNumber = A.ItemNumber)
基本概述:给我最高柜台附属B记录的费用和日期-1。如果没有b记录,请使用A记录信息表示费用,使用12/31/2099表示结束日期。
答案 1 :(得分:0)
我测试了@xQbert提出的查询,但它为您的示例数据返回5行,而不是您请求的4行。
这是一个经过测试的查询,它为您的测试数据返回四行:
select p.Customer, p.ItemNumber, p.EffectDate, coalesce(e.effectdate - interval 1 day, curdate()) EffectiveEnd, p.Cost
from (
select customer, itemnumber, effectdate, max(counter) counter
from prices
group by customer, itemnumber, effectdate
) c
left outer join prices p
on p.customer = c.customer
and p.itemnumber = c.itemnumber
and p.effectdate = c.effectdate
and p.counter = c.counter
left outer join prices e
on e.customer = p.customer
and e.itemnumber = p.itemnumber
and e.effectdate > p.effectdate
and e.counter = p.counter