I wanted to do a similar thing, but using Grafana. I solved it with database views.
First, I created a view on each item table, picking up the latest entry and applying a time shift, for example for the snow prediction:
CREATE DEFINER = 'openhab'@'localhost' VIEW Snow30 AS SELECT 30 AS `hours`, ADDDATE( NOW(), INTERVAL 30 HOUR) AS `forecastdate`, `Item560`.`Value` AS `Value`FROM `Item560`ORDER BY `Item560`.`Time` DESC LIMIT 1;
CREATE DEFINER = 'openhab'@'localhost' VIEW Snow66 AS SELECT 66 AS `hours`, ADDDATE( NOW(), INTERVAL 66 HOUR) AS `forecastdate`, `Item559`.`Value` AS `Value`FROM `Item559`ORDER BY `Item559`.`Time` DESC LIMIT 1;
CREATE DEFINER = 'openhab'@'localhost' VIEW Snow18 AS SELECT 18 AS `hours`, ADDDATE( NOW(), INTERVAL 18 HOUR) AS `forecastdate`, `Item558`.`Value` AS `Value`FROM `Item558`ORDER BY `Item558`.`Time` DESC LIMIT 1;
CREATE DEFINER = 'openhab'@'localhost' VIEW Snow39 AS SELECT 39 AS `hours`, ADDDATE( NOW(), INTERVAL 39 HOUR) AS `forecastdate`, `Item557`.`Value` AS `Value`FROM `Item557`ORDER BY `Item557`.`Time` DESC LIMIT 1;
CREATE DEFINER = 'openhab'@'localhost' VIEW Snow57 AS SELECT 57 AS `hours`, ADDDATE( NOW(), INTERVAL 57 HOUR) AS `forecastdate`, `Item556`.`Value` AS `Value`FROM `Item556`ORDER BY `Item556`.`Time` DESC LIMIT 1;
CREATE DEFINER = 'openhab'@'localhost' VIEW Snow54 AS SELECT 54 AS `hours`, ADDDATE( NOW(), INTERVAL 54 HOUR) AS `forecastdate`, `Item555`.`Value` AS `Value`FROM `Item555`ORDER BY `Item555`.`Time` DESC LIMIT 1;
CREATE DEFINER = 'openhab'@'localhost' VIEW Snow21 AS SELECT 21 AS `hours`, ADDDATE( NOW(), INTERVAL 21 HOUR) AS `forecastdate`, `Item554`.`Value` AS `Value`FROM `Item554`ORDER BY `Item554`.`Time` DESC LIMIT 1;
CREATE DEFINER = 'openhab'@'localhost' VIEW Snow27 AS SELECT 27 AS `hours`, ADDDATE( NOW(), INTERVAL 27 HOUR) AS `forecastdate`, `Item553`.`Value` AS `Value`FROM `Item553`ORDER BY `Item553`.`Time` DESC LIMIT 1;
CREATE DEFINER = 'openhab'@'localhost' VIEW Snow42 AS SELECT 42 AS `hours`, ADDDATE( NOW(), INTERVAL 42 HOUR) AS `forecastdate`, `Item552`.`Value` AS `Value`FROM `Item552`ORDER BY `Item552`.`Time` DESC LIMIT 1;
CREATE DEFINER = 'openhab'@'localhost' VIEW Snow33 AS SELECT 33 AS `hours`, ADDDATE( NOW(), INTERVAL 33 HOUR) AS `forecastdate`, `Item551`.`Value` AS `Value`FROM `Item551`ORDER BY `Item551`.`Time` DESC LIMIT 1;
CREATE DEFINER = 'openhab'@'localhost' VIEW Snow45 AS SELECT 45 AS `hours`, ADDDATE( NOW(), INTERVAL 45 HOUR) AS `forecastdate`, `Item550`.`Value` AS `Value`FROM `Item550`ORDER BY `Item550`.`Time` DESC LIMIT 1;
CREATE DEFINER = 'openhab'@'localhost' VIEW Snow69 AS SELECT 69 AS `hours`, ADDDATE( NOW(), INTERVAL 69 HOUR) AS `forecastdate`, `Item549`.`Value` AS `Value`FROM `Item549`ORDER BY `Item549`.`Time` DESC LIMIT 1;
CREATE DEFINER = 'openhab'@'localhost' VIEW Snow15 AS SELECT 15 AS `hours`, ADDDATE( NOW(), INTERVAL 15 HOUR) AS `forecastdate`, `Item548`.`Value` AS `Value`FROM `Item548`ORDER BY `Item548`.`Time` DESC LIMIT 1;
CREATE DEFINER = 'openhab'@'localhost' VIEW Snow48 AS SELECT 48 AS `hours`, ADDDATE( NOW(), INTERVAL 48 HOUR) AS `forecastdate`, `Item547`.`Value` AS `Value`FROM `Item547`ORDER BY `Item547`.`Time` DESC LIMIT 1;
CREATE DEFINER = 'openhab'@'localhost' VIEW Snow63 AS SELECT 63 AS `hours`, ADDDATE( NOW(), INTERVAL 63 HOUR) AS `forecastdate`, `Item546`.`Value` AS `Value`FROM `Item546`ORDER BY `Item546`.`Time` DESC LIMIT 1;
CREATE DEFINER = 'openhab'@'localhost' VIEW Snow24 AS SELECT 24 AS `hours`, ADDDATE( NOW(), INTERVAL 24 HOUR) AS `forecastdate`, `Item545`.`Value` AS `Value`FROM `Item545`ORDER BY `Item545`.`Time` DESC LIMIT 1;
CREATE DEFINER = 'openhab'@'localhost' VIEW Snow60 AS SELECT 60 AS `hours`, ADDDATE( NOW(), INTERVAL 60 HOUR) AS `forecastdate`, `Item544`.`Value` AS `Value`FROM `Item544`ORDER BY `Item544`.`Time` DESC LIMIT 1;
CREATE DEFINER = 'openhab'@'localhost' VIEW Snow36 AS SELECT 36 AS `hours`, ADDDATE( NOW(), INTERVAL 36 HOUR) AS `forecastdate`, `Item543`.`Value` AS `Value`FROM `Item543`ORDER BY `Item543`.`Time` DESC LIMIT 1;
CREATE DEFINER = 'openhab'@'localhost' VIEW Snow51 AS SELECT 51 AS `hours`, ADDDATE( NOW(), INTERVAL 51 HOUR) AS `forecastdate`, `Item542`.`Value` AS `Value`FROM `Item542`ORDER BY `Item542`.`Time` DESC LIMIT 1;
CREATE DEFINER = 'openhab'@'localhost' VIEW Snow3 AS SELECT 3 AS `hours`, ADDDATE( NOW(), INTERVAL 3 HOUR) AS `forecastdate`, `Item541`.`Value` AS `Value`FROM `Item541`ORDER BY `Item541`.`Time` DESC LIMIT 1;
CREATE DEFINER = 'openhab'@'localhost' VIEW Snow9 AS SELECT 9 AS `hours`, ADDDATE( NOW(), INTERVAL 9 HOUR) AS `forecastdate`, `Item540`.`Value` AS `Value`FROM `Item540`ORDER BY `Item540`.`Time` DESC LIMIT 1;
CREATE DEFINER = 'openhab'@'localhost' VIEW Snow12 AS SELECT 12 AS `hours`, ADDDATE( NOW(), INTERVAL 12 HOUR) AS `forecastdate`, `Item539`.`Value` AS `Value`FROM `Item539`ORDER BY `Item539`.`Time` DESC LIMIT 1;
CREATE DEFINER = 'openhab'@'localhost' VIEW Snow6 AS SELECT 6 AS `hours`, ADDDATE( NOW(), INTERVAL 6 HOUR) AS `forecastdate`, `Item538`.`Value` AS `Value`FROM `Item538`ORDER BY `Item538`.`Time` DESC LIMIT 1;
CREATE DEFINER = 'openhab'@'localhost' VIEW Snow0 AS SELECT 0 AS `hours`, ADDDATE( NOW(), INTERVAL 0 HOUR) AS `forecastdate`, `Item537`.`Value` AS `Value`FROM `Item537`ORDER BY `Item537`.`Time` DESC LIMIT 1;
Then I made a union view to pull each record of the above views in one query:
Create DEFINER = 'openhab'@'localhost' VIEW SnowForecast AS
select hours, forecastdate, Value from Snow0 union
select hours, forecastdate, Value from Snow3 union
select hours, forecastdate, Value from Snow6 union
select hours, forecastdate, Value from Snow9 union
select hours, forecastdate, Value from Snow12 union
select hours, forecastdate, Value from Snow15 union
select hours, forecastdate, Value from Snow18 union
select hours, forecastdate, Value from Snow21 union
select hours, forecastdate, Value from Snow24 union
select hours, forecastdate, Value from Snow27 union
select hours, forecastdate, Value from Snow30 union
select hours, forecastdate, Value from Snow33 union
select hours, forecastdate, Value from Snow36 union
select hours, forecastdate, Value from Snow39 union
select hours, forecastdate, Value from Snow42 union
select hours, forecastdate, Value from Snow45 union
select hours, forecastdate, Value from Snow48 union
select hours, forecastdate, Value from Snow51 union
select hours, forecastdate, Value from Snow54 union
select hours, forecastdate, Value from Snow57 union
select hours, forecastdate, Value from Snow60 union
select hours, forecastdate, Value from Snow63 union
select hours, forecastdate, Value from Snow66 union
select hours, forecastdate, Value from Snow69
I did the same for rain and temperature, and use these three as data sources for a Grafana chart. Unfortunately we are not expecting rain or snow in the coming days, so my chart is pretty boring right now: