Potresti prima fare un self-join sui tassi di cambio che sono ordinati per data in modo da avere la data di inizio e di fine di ogni cambio, senza sovrapposizioni o gap nelle date (magari aggiungilo come visualizzazione al tuo database - nel mio caso sto solo usando un'espressione di tabella comune).
Ora unire quelle tariffe "preparate" alle transazioni è semplice ed efficiente.
Qualcosa come:
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)
Note:
-
Potresti sostituire
GETDATE()
con una data nel lontano futuro, presumo qui che non siano note tariffe per il futuro. -
La regola (B) viene implementata impostando la data del primo tasso di cambio noto sulla data minima supportata da SQL Server
datetime
, che dovrebbe (per definizione se è il tipo che stai usando perDate
colonna) sia il valore più piccolo possibile.