Исходя из вашего запроса, ваша первая проверка должна заключаться в том, что ваш дубль правильно проиндексирован по столбцу даты (и столбцу значений в качестве индекса покрытия). Если это так, то вы можете использовать следующий слегка упрощенный запрос.
Обратите внимание, это заменяет NULL в соответствии с вашим описанием, где ваш заменил 0 вопреки вашему описанию, вам должно быть понятно, какое именно поведение вы хотите.
SELECT
date_column,
COALESCE(
value_column,
(
SELECT lookup.value_column
FROM table_name AS lookup
WHERE lookup.date_column < table_name.date_column
AND lookup.value_column IS NOT NULL
AND table_name.value_column IS NULL
ORDER BY lookup.date_column DESC
LIMIT 1
)
)
FROM
table_name
(на моем телефоне, пожалуйста, прости опечатки)