TIL how to use snowflake's VALUES sub-clause
⋅ 2 minute read
Today I found out about the useful VALUES() sub-clause in snowflake that allows you to dynamically generate a fixed, known set of rows inside your query.
Problem
I had a table exchange_rates
of EUR-currency pairs with their corresponding exchange rates
date | base_currency | target_currency | exchange_rate |
---|---|---|---|
2023-10-03 | ‘EUR’ | ‘GBP’ | 0.87 |
2023-10-03 | ‘EUR’ | ‘USD’ | 1.05 |
2023-10-03 | ‘EUR’ | ‘JPY’ | 155.95 |
that I wanted to join with a table transactions
which contained transaction prices in different currencies:
id | price | price_currency |
---|---|---|
1 | 100.53 | ‘GBP’ |
2 | 1021.68 | ‘EUR’ |
3 | 7.99 | ‘JPY’ |
My goal was to standardize all prices to EUR.
The SQL query to join the two tables would be:
select
id,
price,
price_currency,
exchange_rate
from transactions as t
inner join exchange_rates as er on er.target_currency = t.price_currency
The issue was that exchange_rates
did not have a EUR
-EUR
currency pair and I didn’t have access to the data source. So, the inner join would filter out all EUR transactions (or leave NULLs in case of a left join).
This is a bit of a constructed problem to show an application of VALUES(). One could alternatively fill the NULLs with 1.0s after a left join.
Solution
I used snowflake’s VALUES()
to dynamically generate another row in the query. I use this with a UNION
statement to complete the exchange_rates table before joining:
with exchange_rates_complete as (
select * from exchange_rates
union
select * from (values( '2023-10-03', 'EUR', 'EUR', 1.0, 1))
)
select
id,
price,
price_currency,
exchange_rate
from transactions as t
inner join exchange_rates_complete as er on er.target_currency = t.price_currency
The joined table looks like this:
id | price | price_currency | exchange_rate |
---|---|---|---|
1 | 100.53 | ‘GBP’ | 0.87 |
2 | 1021.68 | ‘EUR’ | 1.0 |
3 | 7.99 | ‘JPY’ | 155.95 |
If you have any thoughts, questions, or feedback about this post, I would love to hear it. Please reach out to me via email.
Tags:#snowflake #sql