我有2个表:budget和budget_rate:
预算表
资源期小时元
-------- ------ ----- -------
ADMIN03 01/31/16 160 8000
ADMIN03 02/28/16 150 7500
费率表
资源率eff_date
-------- ---- --------
ADMIN03 50.00 01/01/16
ADMIN03 52.50 01/01/17
当费率表中的费率发生变化时,我需要根据与资源名称匹配的费率更新预算,并且是早于预算记录的第一个费率记录。
这可以通过一次UPDATE完成吗?
类似的东西:
update b
set b.dollars = b.hours*r.rate
from
budget b join rate r on
b.resource = r.resource and
b.period >= r.eff_date
答案 0 :(得分:1)
我假设费率表很小,所以我会重新计算它以包含范围列。
with oRates as (
select resource,
rate,
eff_date,
ROW_NUMBER() over(partition by resource order by eff_date desc) rn
from Rates
),
pRates as (
select r1.resource,
r1.rate,
r1.eff_date from_date,
isnull(r2.eff_date,'2070-01-01') to_date
from oRates r1
left join oRates r2 on (r1.rn = r2.rn+1)
)
update b
set dollars = hours * r.rate
from Budget b
join pRates r on (b.resource = r.resource
and b.period >= from_date
and b.period < to_date)
答案 1 :(得分:0)
一种可能的解决方案是使用计算列而不是某种手动更新。
可以在此处看到如何完成此操作的示例:formula for computed column based on different table's column
对于数据的工作示例,您需要创建如下函数:
CREATE FUNCTION dbo.ufn_BudgetDollars (@resource NVARCHAR(255), @date DATE, @hours INT)
RETURNS DECIMAL(10, 2)
AS BEGIN
DECLARE @out DECIMAL(10, 2);
SELECT @out = @hours * rate
FROM (
SELECT rate, ROW_NUMBER() OVER (ORDER BY eff_date DESC) rn
FROM tblRate
WHERE eff_date <= @date
AND resource = @resource) T
WHERE RN = 1;
RETURN @out;
END
GO
创建功能后,您需要删除并重新创建预算表中的Dollars列...
ALTER TABLE tblBudget DROP COLUMN Dollars;
ALTER TABLE tblBudget ADD Dollars AS dbo.ufn_BudgetDollars(resource, Period, Hours);
GO