我有两张桌子:
比尔:
create table Bill(
BillDate datetime,
Amount decimal(10,2) ,
BillCurrency varchar(3) ,
ReportingCurrency decimal(10,2))
FxRate:
create table FxRate(
RateDate datetime,
SourceCurrency varchar(3),
TargetCurrency varchar(3),
ExchangeRate decimal(15,4))
这就是我想要做的事情:
我想将我的比尔表更新为
update Bill
set ReportingCurrency = FxRate.ExchangeRate * Bill.Amount
from FxRate
where FxRate.RateDate = Bill.BillDate
在此更新中,具有该特定日期条目的所有行将获得新的reportingcurrency数据。由于Bill表可以有多行符合更新条件,因此我遇到以下问题:
对于FxRate表中没有条目的行(对于该日期),ReportingCurrency变为NULL。我想回到nearest <= RateDate
并获取汇率。是否可以在同一更新声明中使用修改或其他一些有效的方法? (我想避开光标)。
答案 0 :(得分:1)
您应该可以使用子查询来实现此目的。希望我下面的例子可以不加修改地工作(并且没有错误!)唯一的注意事项是你需要用你的报告(基础)货币代替我假设的“美元”。
UPDATE Bill SET ReportingCurrency = (Bill.Amount *
(SELECT TOP 1 FxRate.ExchangeRate FROM FxRate
WHERE FxRate.SourceCurrency = Bill.BillCurrency
AND FxRate.TargetCurrency = 'USD'
AND FxRate.RateDate <= Bill.BillDate
ORDER BY FxRate.RateDate DESC))
希望这会有所帮助。编辑 - 添加了ORDER BY子句
答案 1 :(得分:0)
当然这是可能的 - 作为SELECT,这将是:
SELECT
b.BillDate,
r.RateDate,
r.ExchangeRate
FROM
Bill b
LEFT JOIN FxRate r ON r.RateDate = (
SELECT MAX(RateDate) FROM FxRate WHERE RateDate <= b.BillDate
)
因此,作为更新:
UPDATE
Bill
SET
ReportingCurrency = r.ExchangeRate * b.Amount
FROM
Bill b
LEFT JOIN FxRate r ON r.RateDate = (
SELECT MAX(RateDate) FROM FxRate WHERE RateDate <= b.BillDate
)
解决方案做出以下假设:
FxRate
FxRate
条记录早于所有Bill
条记录如果这些假设不适用,则必须接受查询。
另请注意,这是SQL Server语法。 Sybase可能有点不同。
由于评论者对一般的“最近日期”解决方案表现出兴趣:
UPDATE
Bill
SET
ReportingCurrency = r.ExchangeRate * b.Amount
FROM
Bill b
LEFT JOIN FxRate r ON r.RateDate = (
SELECT TOP 1 RateDate
FROM FxRate
ORDER BY ABS(DATEDIFF(d, RateDate, b.BillDate)), RateDate
)
但这会很慢。替代方法:
UPDATE
Bill
SET
ReportingCurrency = CASE
WHEN DATEDIFF(d, r1.RateDate, b.BillDate) <= DATEDIFF(d, b.BillDate, r2.RateDate)
THEN r1.ExchangeRate
ELSE COALESCE(r2.ExchangeRate, r1.ExchangeRate)
END * b.Amount
FROM
Bill b
LEFT JOIN FxRate r1 ON r1.RateDate = (
SELECT MAX(RateDate) FROM FxRate WHERE RateDate <= b.BillDate
)
LEFT JOIN FxRate r2 ON r2.RateDate = (
SELECT MIN(RateDate) FROM FxRate WHERE RateDate >= b.BillDate
)