My JOIN does not work. The data stays NULL
Hi, this is my first question, so please be nice. Think twice before hitting the "minus" button.
1/ I have a volatility
AS bv table with he following fields:
- bv.
Ticker
- bv.
Vol_ref
- bv.
Volatility
- bv.
Database_time_milsec
2/ bv.Vol_ref
can be 1 of 4 : ’10m-30m’, ‘5m-30m’, ‘5m-1h’ or ’10m-1h’.
3/ I have a tradebook
AS atb table that i want to fill with onfo from bv.
- atb.
10m_1h_vol
: the last bv.Volatility
where atb.ticker =
bv.Ticker
and bv.Vol_ref
=’10m-1h’ - atb.
10m_30m_vol
: the last bv.Volatility
where atb.ticker =
bv.Ticker
and bv.Vol_ref
=’10m-30m’ - atb.
5m_1h_vol
: the last bv.Volatility
where atb.ticker =
bv.Ticker
and bv.Vol_ref
=’5m-1h’ - atb.
5m_30m_vol
: the last bv.Volatility
where atb.ticker =
bv.Ticker
and bv.Vol_ref
=’5m-30m’
My strategy is :
1/ get the latest bv.Database_time_milsec per bv.
Vol_ref and bv.
Ticker`
SELECT
Ticker,
MAX(CASE WHEN Vol_ref = '10m-30m' THEN `Database_Time_milsec` END) AS `max_time_10m_30m`,
MAX(CASE WHEN Vol_ref = '5m-30m' THEN `Database_Time_milsec` END) AS `max_time_5m_30m`,
MAX(CASE WHEN Vol_ref = '5m-1h' THEN `Database_Time_milsec` END) AS `max_time_5m_1h`,
MAX(CASE WHEN Vol_ref = '10m-1h' THEN `Database_Time_milsec` END) AS `max_time_10m_1h`
FROM
volatility
GROUP BY
`Ticker`
) AS bv_max_time
2/ use these max time to get the latest vol and insert it:
UPDATE `tradebook` AS atb
JOIN (
SELECT
Ticker,
MAX(CASE WHEN Vol_ref = '10m-30m' THEN `Database_Time_milsec` END) AS `max_time_10m_30m`,
MAX(CASE WHEN Vol_ref = '5m-30m' THEN `Database_Time_milsec` END) AS `max_time_5m_30m`,
MAX(CASE WHEN Vol_ref = '5m-1h' THEN `Database_Time_milsec` END) AS `max_time_5m_1h`,
MAX(CASE WHEN Vol_ref = '10m-1h' THEN `Database_Time_milsec` END) AS `max_time_10m_1h`
FROM
volatility
GROUP BY
`Ticker`
) AS bv_max_time ON atb.`ticker` = bv_max_time.`Ticker`
JOIN `volatility` AS bv ON atb.`ticker` = bv.`Ticker`
SET
atb.`10m_1h_vol` = CASE WHEN bv.`Database_Time_milsec` = bv_max_time.`max_time_10m_1h` THEN bv.`Volatility` END,
atb.`10m_30m_vol` = CASE WHEN bv.`Database_Time_milsec` = bv_max_time.`max_time_10m_30m` THEN bv.`Volatility` END,
atb.`5m_1h_vol` = CASE WHEN bv.`Database_Time_milsec` = bv_max_time.`max_time_5m_1h` THEN bv.`Volatility` END,
atb.`5m_30m_vol` = CASE WHEN bv.`Database_Time_milsec` = bv_max_time.`max_time_5m_30m` THEN bv.`Volatility` END;
but it does not work. The data does not get joined and the atb fields stay NULL
2
Answers
====================== SOLUTION FOUND ==================
I ditched the JOIN technique, although it is my favourite and went nuclear. It is NOT elegant, but it works:
comments and improvement welcome
You attempt to update all the atb columns for each bv row with the ticker. It looks to me like if the
set...case when
happens to be true for the last bv row it encounters (where no order is guaranteed) it will set a value, otherwise it will leave it null.You would need to get the volatility for the max times in your subquery to do this (and not join bv outside the subquery), either using window functions or using
substr(max(case...then concat...
as shown in https://stackoverflow.com/a/72568199 (exactly how is dependent on what type Database_time_milsec is).Or alternatively, clear all the atb values first, and then have your update set them conditionally, e.g.: