Okay so I suck at SQL... If I have a table Forecasts in SQL Server (2015+) with columns CityName, WeatherProviderName, TimeStamp, TempCelcius, And what I want out of it is the forecasts for every city from every weather provider that has been reported in the last 2 days, plus the latest forecast for every City+Provider that has not forecast anything in the last 2 days.
Is there a single query to get this that is more performant that just requesting the 2 separately? I know I can get the latest values (based off this article) like this:
select t.CityName, t.WeatherProviderName, t.TimeStamp, t.TempCelcius from Forecasts t
inner join (
select CityName, WeatherProviderName, TempCelcius, max(TimeStamp) as maxTime
from Forecasts where TimeStamp < DATEADD(DAY,-2, GETDATE())
group by CityName, WeatherProviderName
) tm on t.CityName = tm.CityName AND t.WeatherProviderName = tm.WeatherProviderName AND t.TimeStamp = tm.maxTime
(also tried with the partition from that SO question, but it was more than 3 times slower for my test set)
I can get everything for the last 2 days with:
select CityName, WeatherProviderName, TimeStamp, TempCelcius from Forecasts where TimeStamp > DATEADD(DAY,-2, GETDATE())
but rather than running them both into 2 collections and combining, is there a way to get them both in a quick single query?
Note on Answer
I went with the union as suggested by @Forklift (thanks) in the comment below. It's the fastest of the options suggested. It looked like this:
SELECT t.CityName, t.WeatherProviderName, t.TimeStamp, t.TempCelcius FROM
Forecasts t
INNER JOIN (
SELECT CityName, WeatherProviderName, TempCelcius, max(TimeStamp) AS maxTime
FROM Forecasts WHERE TimeStamp < DATEADD(DAY,-2, GETDATE())
GROUP BY CityName, WeatherProviderName
) tm ON t.CityName = tm.CityName AND t.WeatherProviderName = tm.WeatherProviderName AND t.TimeStamp = tm.maxTime
UNION
SELECT CityName, WeatherProviderName, TimeStamp, TempCelcius FROM Forecasts WHERE TimeStamp > DATEADD(DAY,-2, GETDATE())
I have also marked @SqlZsm as the answer because it does do it in a single query... so depending on your exact need you have either @Forklift or @SqlZsm to thank :)