I have a query in an Oracle database that I am hoping to simplify. I have done something similar with a PIVOT before, but not something this complex. I have two tables, WEATHER AND TELEMETRY. The query is for an ancient report that ties several values from several weather readings to the telemetry data. The weather data looks like this:
| READING_DATE | HOUR_VALUE | STATION_ID | TEMPERATURE | HUMIDITY | WIND | CONDITIONS |
|---|---|---|---|---|---|---|
| 08/01/2022 | 1 | station1 | 77 | 50 | 1 | clear |
| 08/01/2022 | 1 | station2 | 75 | 50 | 0 | clear |
| 08/01/2022 | 1 | station3 | 74 | 60 | 3 | overcast |
| 08/01/2022 | 2 | station1 | 76 | 50 | 3 | clear |
| 08/01/2022 | 2 | station2 | 74 | 50 | 0 | clear |
| 08/01/2022 | 2 | station3 | 70 | 65 | 2 | overcast |
| 08/01/2022 | 3 | station1 | 73 | 60 | 5 | cloudy |
| 08/01/2022 | 3 | station2 | 71 | 70 | 2 | cloudy |
| 08/01/2022 | 3 | station3 | 69 | 100 | 3 | rain |
The telemetry table looks like this:
| READING_DATE | HOUR_VALUE | TELEMETRY_VALUE_1 | TELEMETRY_VALUE_2 |
|---|---|---|---|
| 08/01/2022 | 1 | 430 | 10 |
| 08/01/2022 | 2 | 405 | 9 |
| 08/01/2022 | 3 | 390 | 8 |
The telemetry values are only tied to the date and hour, not to the station ids. The desired result is a query that lays out the temperature, wind, humidity, and conditions for each hour as shown below (the temp, wind, humidity and conditions repeat for up to 10 stations, but I cut it off after two here):
| READING_DATE | HOUR_VALUE | TELEMETRY_VALUE_1 | C1_TEMP | C1_WIND | C1_HUMIDITY | C1_CONDITIONS | C2_TEMP | C2_WIND | C2_HUMIDITY | C2_CONDITIONS |
|---|---|---|---|---|---|---|---|---|---|---|
| 08/01/2022 | 1 | 430 | 77 | 1 | 50 | clear | 75 | 0 | 50 | clear |
| 08/01/2022 | 2 | 405 | 76 | 3 | 50 | clear | 74 | 0 | 50 | clear |
| 08/01/2022 | 3 | 390 | 73 | 5 | 60 | overcast | 71 | 2 | 70 | cloudy |
The report has a working query, which is shown below. Would it be possible to refactor this somehow using a pivot or some other method so that I don't have to individually select every piece of data for every station?
select a.reading_date,
a.hour_value,
a.telemetry_value_1,
(select AVG(temperature) from WEATHER_ACTUALS b where station_id = 'station1' and reading_date = a.reading_date and hour_value = a.hour_value) as c1_temp,
(select AVG(wind) from WEATHER_ACTUALS b where station_id = 'station1' and reading_date = a.reading_date and hour_value = a.hour_value) as c1_wind,
(select AVG(humidity) from WEATHER_ACTUALS b where station_id = 'station1' and reading_date = a.reading_date and hour_value = a.hour_value) as c1_humidity,
(select conditions from WEATHER_ACTUALS b where rownum = 1 and station_id = 'station1' and reading_date = a.reading_date and hour_value = a.hour_value) as c1_conditions,
(select AVG(temperature) from WEATHER_ACTUALS b where station_id = 'station2' and reading_date = a.reading_date and hour_value = a.hour_value) as c2_temp,
(select AVG(wind) from WEATHER_ACTUALS b where station_id = 'station2' and reading_date = a.reading_date and hour_value = a.hour_value) as c2_wind,
(select AVG(humidity) from WEATHER_ACTUALS b where station_id = 'station2' and reading_date = a.reading_date and hour_value = a.hour_value) as c2_humidity,
(select conditions from WEATHER_ACTUALS b where rownum = 1 and station_id = 'station2' and reading_date = a.reading_date and hour_value = a.hour_value) as c2_conditions,
...
(select AVG(temperature) from WEATHER_ACTUALS b where station_id = 'station10' and reading_date = a.reading_date and hour_value = a.hour_value) as c10_temp,
(select AVG(wind) from WEATHER_ACTUALS b where station_id = 'station10' and reading_date = a.reading_date and hour_value = a.hour_value) as c10_wind,
(select AVG(humidity) from WEATHER_ACTUALS b where station_id = 'station10' and reading_date = a.reading_date and hour_value = a.hour_value) as c10_humidity,
(select conditions from WEATHER_ACTUALS b where rownum = 1 and station_id = 'station10' and reading_date = a.reading_date and hour_value = a.hour_value) as c10_conditions
from telemetry_data a
where a.reading_date between :beginDate and :endDate