Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Join SQL rispetto a intervalli di date?

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 per Date colonna) sia il valore più piccolo possibile.