I have a table with daily exchange rates from ECB
FXDate EUR USD AUD BGN BRL CAD CHF ....
30/06/2017 00:00 1.00 1.1412 1.4851 1.9558 3.76 1.4785 1.093
29/06/2017 00:00 1.00 1.1413 1.4868 1.9558 3.7476 1.4867 1.0935
28/06/2017 00:00 1.00 1.1375 1.4986 1.9558 3.7632 1.4888 1.0913
27/06/2017 00:00 1.00 1.1278 1.4819 1.9558 3.7216 1.4895 1.0883
26/06/2017 00:00 1.00 1.1187 1.4771 1.9558 3.7259 1.4812 1.0881
23/06/2017 00:00 1.00 1.1173 1.4764 1.9558 3.7293 1.4783 1.0851
22/06/2017 00:00 1.00 1.1169 1.4812 1.9558 3.7164 1.4853 1.0867
21/06/2017 00:00 1.00 1.1147 1.4738 1.9558 3.7028 1.4803 1.0857
20/06/2017 00:00 1.00 1.1156 1.4674 1.9558 3.6845 1.4812 1.0854
19/06/2017 00:00 1.00 1.1199 1.4705 1.9558 3.6957 1.4827 1.087
then I have a sales table like this:
UserName Purchasedate Currency Price Quantity
John 24/06/2017 14:53 EUR 5.4 3
Jude 24/06/2017 18:47 USD 4 2
Jack 25/06/2017 07:34 USD 6.35 2
Jill 25/06/2017 11:42 EUR 4.15 1
Joe 26/06/2017 11:13 USD 4.50 1
I need to create a table where I have the latest exchange rate for the given Currency, and a summary of daily amount, if possible, like this:
UserName PurchaseDate Currency Price Quantity ExchangeRate ConvertedAmountEUR
John 24/06/2017 EUR 5.4 3 1.00 16.20
Jude 24/06/2017 USD 4 2 1.1173 8.94 //Exchange rate of 23rd since for 24th is not available
DAILY TOTAL 24/06/2017 25.14
Jack 25/06/2017 USD 6.35 2 1.1173 14.19 //Exchange rate of 23rd since for 24th is not available
Jill 25/06/2017 EUR 4.15 1 1.00 4.15
DAILY TOTAL 25/06/2017 18.34
Joe 26/06/2017 USD 4.50 1 1.1187 5.03 //Exchange rate of 26th
DAILY TOTAL 26/06/2017 5.03
I tried with cross join to extract the right exchange rate but there is the problem of the "not matching days"
while cannot use rollup for subtotal since it requires grouping while I need separated rows for each purchase
can suggest even a partial solution?
Thanks
Best Answer
This can be done in a step-by-step fashion.
First: we have the table
sales
differentiating between thePurchaseDateTime
and thePurchaseDate
:This will make our life easier, as we already have the date precomputed.
Next thing you need to do is to unpivot your
exchange_rate
table:NOTE: I've used the name
exchange_rates_pivot
for your original pivoted exchange rates table.You need this intermediate step to be able to do later on the proper JOINs (you can't actually JOIN in row and column. You cannot treat column names as if they were values [at least, not in any easy fashion]).
You can also use the
UNPIVOT
infrastructure from SQL Server, but this is more SQL Standard, although probably not as efficient.The content of this table looks like:
Second thing you need to do is finding the exchange rate for all your
sales
and put the info together.For each specific purchase, the exchange rate is found by means of:
Note that the combination of
TOP 1
andORDER BY
will give you the currency exchange for the day, and if not available, for the closest previous date where this info is available; as I've inferred from your example. For the sake of completeness, it should actually be divided by the exchange rate of EUR, in case the exchange data is not based on EUR = 1.00. I haven't done at this point not to overcomplicate things.This will lead us to the following query:
... which results in:
Last, we compute also the 'DAILY TOTAL', and perform a
UNION ALL
with what we already have. AWITH
statement comes in handy in this case. Some smallish trickery is needed to ease the ordering (look for theOrderBy
column).This is done with the following statement:
... whose result is:
You can check all the step-by-step details at dbfiddle here
If you would need everything in just one statement, you could put the equivalent of #exchange_rate as part of the WITH. This will give you a very large statement, not so easy to read... For the all-in-one version dbfiddle here