0
votes

There is a table A which has Start and End Date, Price and CurrencyCode. There is a table B which has historical + Today's Exchange Rates. I need to convert table A Price based on the following assumptions:

  • For the Historical Dates (I.e Start & End Date) < Today's Date, I will get their average exchange rate and use that for the conversion.
  • Any future Date (Date > Today) will use today's exchange rate.

Esentially, I need to get an average Exchange Rate for the Duration of the WeekStart - WeekEnd Date.

Here is a schema/ some sample data for Table B which contains the Exchange Rate.

    DateTime                     Date       FromCurrCode  ToCurrCode   Rate
    2016-07-07 07:16:12.000       2016-07-07    USD        CAD         1.2939
    2016-07-06 07:27:12.000       2016-07-06    USD        CAD         1.3017
    2016-07-05 07:34:07.000       2016-07-05    USD        CAD         1.2922
    2016-07-04 07:42:07.000       2016-07-04    USD        CAD         1.2853
    2016-07-03 07:52:06.000       2016-07-03    USD        CAD         1.2908
    2016-07-02 07:06:08.000       2016-07-02    USD        CAD         1.2915
    

Here is a schema/sample data for Table A which has the WeekStart and WeekEnd Dates:

order#      WeekStart                        WeekEnd                    Curr
1256      2016-07-04 00:00:00.000            2016-07-10 00:00:00.000    USD
1255      2016-07-04 00:00:00.000            2016-07-10 00:00:00.000    USD 

Based on Table B, because the End Date goes into the future, the average rate should be calculated as the following:

2016-07-04 ---- Use historical currency
2016-07-05 ---- Use historical currency
2016-07-06 ---- Use historical currency
2016-07-07 ---- Use today's currency rate 
2016-07-08 ---- Use today's currency rate 
2016-07-09 ---- Use today's currency rate 
2016-07-10 ---- Use today's currency rate 

Then using these rates above, it should return an Average Rate as a column for each of Rows in Table A.

However, if the WeekStart and WeekEnd dates were in the past and less than today's date, then it would just calculate the average for the Start-End using the historical rate in table B.

Am I correct to assume this can be done via function? That would be the best approach. If so what would the function implementation look like.

1
You don't need a function you can do it via a query. So what if start date is prior to today and end date is after should that be averaged or use todays rate?Matt
Also if you can post your schema it would be good.Matt
That is the case that is described above. In this case, exchange rates from today()+1 until end date would be today's exchange rate and it would get the historical date and then average at the end.user1347948
@Matt Please let me know how this can be done via Query.user1347948
No worries I am writing something, I probably should have asked a minute ago but if you have some sample data for the tables it would be good.Matt

1 Answers

0
votes
DECLARE @ToCurrCode CHAR(3) = 'CAD'

;WITH cteTally AS (
    SELECT 0 AS I
    UNION ALL
    SELECT I + 1 AS I
    FROM
       cteTally
    WHERE i + 1 <= 6
)

SELECT
    a.OrderNum
    ,AVG(b.Rate) AS AvgRate
FROM
    TableA a
    INNER JOIN cteTally t
    ON DATEDIFF(day,a.WeekStart,a.WeekEnd) >= t.I
    LEFT JOIN TableB b
    ON (CASE
          WHEN DATEADD(day,t.i,a.WeekStart) <= CAST(GETDATE() AS DATE) THEN DATEADD(day,t.i,a.WeekStart)
          ELSE CAST(GETDATE() AS DATE)
       END) = b.[Date]
       AND a.Curr = b.FromCurrCode
       AND b.ToCurrCode = @ToCurrCode
GROUP BY
    a.OrderNum

Create a Tally Table with a recursive common table expression [CTE] that will essentially make your 1 week long record into x# of days. This is 0 based so 6 is actually 7 days.

Join that to the orders to create a row for every day by using.

Join that to your exchange rate table, use a similar case statement to my previous answer that says when the date is >= today then use today's date for the join. Notice I am using a left join just in case you have missing data.

Then do your aggregation and get your average.