Você pode primeiro fazer uma auto-junção nas taxas de câmbio que são ordenadas por data para que você tenha a data inicial e final de cada taxa de câmbio, sem sobreposição ou lacuna nas datas (talvez adicione isso como visualização ao seu banco de dados - no meu caso estou apenas usando uma expressão de tabela comum).
Agora juntar essas taxas "preparadas" com as transações é simples e eficiente.
Algo como:
WITH IndexedExchangeRates AS (
SELECT Row_Number() OVER (ORDER BY Date) ix,
Date,
Rate
FROM ExchangeRates
),
RangedExchangeRates AS (
SELECT CASE WHEN IER.ix=1 THEN CAST('1753-01-01' AS datetime)
ELSE IER.Date
END DateFrom,
COALESCE(IER2.Date, GETDATE()) DateTo,
IER.Rate
FROM IndexedExchangeRates IER
LEFT JOIN IndexedExchangeRates IER2
ON IER.ix = IER2.ix-1
)
SELECT T.Date,
T.Amount,
RER.Rate,
T.Amount/RER.Rate ConvertedAmount
FROM Transactions T
LEFT JOIN RangedExchangeRates RER
ON (T.Date > RER.DateFrom) AND (T.Date <= RER.DateTo)
Observações:
-
Você pode substituirGETDATE()
com uma data no futuro distante, estou assumindo aqui que nenhuma taxa para o futuro é conhecida.
-
A regra (B) é implementada definindo a data da primeira taxa de câmbio conhecida para a data mínima suportada pelo SQL Serverdatetime
, que deve (por definição, se for o tipo que você está usando para oDate
coluna) seja o menor valor possível.