Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Jointure SQL par rapport aux plages de dates ?

Vous pouvez d'abord faire une auto-jointure sur les taux de change qui sont classés par date afin d'avoir la date de début et de fin de chaque taux de change, sans aucun chevauchement ni écart dans les dates (peut-être ajouter cela comme vue dans votre base de données - dans mon cas, j'utilise simplement une expression de table commune).

Désormais, joindre ces tarifs "préparés" aux transactions est simple et efficace.

Quelque chose comme :

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)

Remarques :

  • Vous pouvez remplacer GETDATE() avec une date dans un futur lointain, je suppose ici qu'aucun taux pour le futur n'est connu.

  • La règle (B) est implémentée en fixant la date du premier taux de change connu à la date minimale supportée par le SQL Server datetime , qui devrait (par définition si c'est le type que vous utilisez pour la Date colonne) soit la plus petite valeur possible.