Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

SQL-Join gegen Datumsbereiche?

Sie könnten zuerst eine Selbstverbindung zu den nach Datum geordneten Wechselkursen erstellen, sodass Sie das Start- und Enddatum jedes Wechselkurses ohne Überschneidungen oder Lücken in den Daten haben (vielleicht fügen Sie dies als Ansicht zu Ihrer Datenbank hinzu - in meinem Fall verwende ich nur einen gemeinsamen Tabellenausdruck).

Jetzt ist es einfach und effizient, diese "vorbereiteten" Kurse mit den Transaktionen zu verbinden.

Etwas wie:

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)

Hinweise:

  • Sie könnten GETDATE() ersetzen mit einem Datum in ferner Zukunft gehe ich hier davon aus, dass keine Kurse für die Zukunft bekannt sind.

  • Regel (B) wird implementiert, indem das Datum des ersten bekannten Wechselkurses auf das Mindestdatum gesetzt wird, das von SQL Server datetime unterstützt wird , was (per Definition, wenn es der Typ ist, den Sie für das Date verwenden Spalte) der kleinstmögliche Wert sein.