By the way, great post. I took the query provided and furthered refined it for jobs that have no history; you may have created a job yesterday that was supposed to run today. Also keep in mind that the query will return all columns and rows, so it's up to you to figure out which columns you want to see.
Select *
From msdb.dbo.sysjobs j with(nolock)
Inner Join msdb.dbo.sysjobschedules s with(nolock) on s.job_id = j.job_id
Outer Apply(
Select *,
RankID = Dense_Rank() Over(Partition By job_id Order By convert(varchar,run_date)+ ' ' + RIGHT('000000'+CONVERT(varchar, run_time),6) Desc)
From msdb.dbo.sysjobhistory with(nolock)
where
job_id = j.job_id) h
where
(h.RankID = 1 Or h.RankID Is Null) And
(h.run_date < s.next_run_date or h.run_date is null) and
(h.run_time < s.next_run_time or h.run_time is null) and
convert(date,convert(varchar(8),ISNULL(NULLIF(s.next_run_date,0),19000101)),112) < convert(date, getdate())