Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

SQL junta-se a intervalos de datas?


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 substituir GETDATE() 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 Server datetime , que deve (por definição, se for o tipo que você está usando para o Date coluna) seja o menor valor possível.