I am doing traffic analysis and I have an aggregated view of average travel times with traffic. What I am attempting to do is select the time associated with the max average travel time for the given time periods.
Here is the code and results I am looking for, without time:
SELECT dt.datekey, dt.peak_hours, dt.weekday_name,
ROUND(MAX(avg_t_dur_traffic)/60,2) MaxATT
FROM cat.Analytics_AvgTimes att
INNER JOIN cat.Dim_Date dt on att.DateKey = dt.DateKey and att.timekey = dt.timekey
WHERE dt.DateKey = '20170523' AND dt.peak_hours <> 'off_peak'
GROUP BY dt.DateKey, dt.Peak_Hours, dt.Weekday_Name
datekey peak_hours weekday_name MaxATT
2017-05-23 AM_Peak Tuesday 28.93
2017-05-23 Midday_Peak Tuesday 14.05
2017-05-23 PM_Peak Tuesday 29.95
Edit: I'm not looking specifically for these three MaxATT times, I'm only looking for help on how to query the information...
I see the Max Average Trip Time (MaxATT) during AM peak hours on Tuesday approx. 29 minutes. When I add in time is where I am having a hard time. I get the following results:
Please note that I have removed a few rows from the results to save on space
SELECT dt.datekey, dt.TimeKey, dt.peak_hours, dt.weekday_name,
ROUND(MAX(avg_t_dur_traffic)/60,2) MaxATT
FROM cat.Analytics_AvgTimes att
INNER JOIN cat.Dim_Date dt on att.DateKey = dt.DateKey and att.timekey = dt.timekey
WHERE dt.DateKey = '20170523' and dt.peak_hours <> 'off_peak'
GROUP BY dt.DateKey, dt.Peak_Hours, dt.Weekday_Name, dt.TimeKey
datekey TimeKey peak_hours weekday_name MaxATT
2017-05-23 05:15:00 AM_Peak Tuesday 10.43
2017-05-23 05:30:00 AM_Peak Tuesday 10.45
2017-05-23 07:15:00 AM_Peak Tuesday 12.53
2017-05-23 07:30:00 AM_Peak Tuesday 18.27
2017-05-23 07:45:00 AM_Peak Tuesday 22.85
2017-05-23 08:00:00 AM_Peak Tuesday 28.93
We can see the time associated with MaxATT = 28.93 is 08:00 during the AM peak. But all I want to select is each distinct time during each peak, so what I am looking for is
datekey TimeKey peak_hours weekday_name MaxATT
2017-05-23 08:00:00 AM_Peak Tuesday 28.93
2017-05-23 13:45:00 Midday_Peak Tuesday 14.05
2017-05-23 17:30:00 PM_Peak Tuesday 29.95
Here is an attempt at using RANK(), but I failed miserably as MaxATT does not match the correct value, and it pulls more records than just RANK() = 1
SELECT id, datekey, peak_hours, weekday_name, MaxAtt
FROM(
SELECT id, dt.DateKey, dt.Peak_Hours, dt.Weekday_Name,
ROUND(MAX(avg_t_dur_traffic)/60,2) MaxAtt,
RANK() OVER(PARTITION BY id ORDER BY MAX(avg_t_dur_traffic) DESC) AS
[rank]
FROM cat.Analytics_AvgTimes att
INNER JOIN cat.Dim_Date dt ON att.datekey = dt.DateKey AND att.TimeKey = dt.TimeKey
GROUP BY id, dt.DateKey, dt.Peak_Hours, dt.Weekday_Name
) mt
WHERE mt.[rank] = 1 AND DateKey = '20170523' AND peak_hours <> 'off_peak'
GROUP BY id, datekey, peak_hours, weekday_name, MaxAtt
Thank you for the help and if you need further clarification please feel free to ask!
Use a subquery to find the maxatt rows needed and they join that to the original table.
select a.*
from cat.Analytics_AvgTimes a
Inner JOIN (
select datekey, peak_hours, weekday_name, max(maxatt) as maxatt
from cat.Analytics_AvgTimes
group by datekey, peak_hours, weekday_name) b
ON a.datekey = b.datekey and a.peak_hours = b.peak_hours and
a.weekday_name = b.weekday_name and a.maxatt = b.maxatt
fiddle example http://sqlfiddle.com/#!9/dcacb9/1/0
edit after reviewing data:
select one.*
from (select a.*, b.Avg_T_Dur_Traffic as max
from dim_date a, Analytics_AvgTimes b
where a.datekeyid = b.id) one
INNER JOIN (
select a.*, max(b.Avg_T_Dur_Traffic) as max
from dim_date a, Analytics_AvgTimes b
where a.datekeyid = b.id
group by datekey, monthid, weekid, dayid, peakhoursid) two
ON one.datekey = two.datekey and one.monthid = two.monthid and
one.weekid = two.weekid and one.dayid = two.dayid and one.max = two.max
fiddle with provided data: http://sqlfiddle.com/#!9/d7889a/9
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.