我们有一个交通计数器,以15分钟为增量对每个车道(两个入站和两个出站)的车辆进行计数。
有一个高峰期定义为上午7:00至9:00。在这个高峰期内,我们想知道 PeakHourIn 和 PeakHourOut 和 PeakHourSum 。
PeakHourIn 是lne1in + lne4in连续4x15分钟最长(1小时)
PeakHourOut 是lne2out + lne3out最高连续4x15分钟(1小时)
PeakHourSum 是所有泳道连续4x15分钟(1小时)的最高分。
Date Time lne1in lne2out lne3out lne4in
09-18-2012 5:45 AM 2 0 0 0
09-18-2012 6:00 AM 1 0 0 1
09-18-2012 6:15 AM 2 1 0 0
09-18-2012 6:30 AM 2 1 0 0
09-18-2012 6:45 AM 6 1 2 1
09-18-2012 7:00 AM 9 1 0 3
09-18-2012 7:15 AM 81 12 22 15
09-18-2012 7:30 AM 144 31 63 56
09-18-2012 7:45 AM 84 30 62 42
09-18-2012 8:00 AM 7 1 0 3
09-18-2012 8:15 AM 11 2 3 3
09-18-2012 8:30 AM 12 3 7 1
09-18-2012 8:45 AM 16 4 8 0
09-18-2012 9:00 AM 5 2 5 0
09-18-2012 9:15 AM 10 1 4 0
结果应该如下:
PeakHourIn 434 PeakHourOut 221 PeakHourSum 655
非常感谢任何帮助。
答案 0 :(得分:1)
如果您使用本机时态数据类型来存储日期/时间,则可以对多个自连接进行分组:
SELECT MAX(lne1in + lne4in ) AS PeakHourIn,
MAX(lne2out + lne3out) AS PeakHourOut,
MAX(lne1in + lne2out + lne3out + lne4in) AS PeakHourSum
FROM (
SELECT t1.lne1in + t2.lne1in + t3.lne1in + t4.lne1in AS lne1in,
t1.lne2out + t2.lne2out + t3.lne2out + t4.lne2out AS lne2out,
t1.lne3out + t2.lne3out + t3.lne3out + t4.lne3out AS lne3out,
t1.lne4in + t2.lne4in + t3.lne4in + t4.lne4in AS lne4in
FROM my_table t1
JOIN my_table t2 ON t2.DateTime = t1.DateTime + INTERVAL 15 MINUTE
JOIN my_table t3 ON t3.DateTime = t2.DateTime + INTERVAL 15 MINUTE
JOIN my_table t4 ON t4.DateTime = t3.DateTime + INTERVAL 15 MINUTE
WHERE TIME(t1.DateTime) BETWEEN '07:00:00' AND '08:00:00'
GROUP BY t1.DateTime
) t
答案 1 :(得分:0)
修改强>
以下是MySQL的解决方案:http://sqlfiddle.com/#!2/ff0fb/9
创建表TrafficData
(
StartTime时间戳
,Lane int
,CarCount int
);
create table LaneData
(
Lane int
, Direction bit
);
insert LaneData
select 1, 0
union select 2, 1
union select 3, 1
union select 4, 0;
insert TrafficData
select dt, lane
, case lane
when 1 then l1
when 2 then l2
when 3 then l3
when 4 then l4
else null
end
from
(
select '2012-09-18 05:45' dt, 2 l1, 0 l2, 0 l3, 0 l4
union all select '2012-09-18 06:00', 1, 0, 0, 1
union all select '2012-09-18 06:15', 2, 1, 0, 0
union all select '2012-09-18 06:30', 2, 1, 0, 0
union all select '2012-09-18 06:45', 6, 1, 2, 1
union all select '2012-09-18 07:00', 9, 1, 0, 3
union all select '2012-09-18 07:15', 81, 12, 22, 15
union all select '2012-09-18 07:30', 144, 31, 63, 56
union all select '2012-09-18 07:45', 84, 30, 62, 42
union all select '2012-09-18 08:00', 7, 1, 0, 3
union all select '2012-09-18 08:15', 11, 2, 3, 3
union all select '2012-09-18 08:30', 12, 3, 7, 1
union all select '2012-09-18 08:45', 16, 4, 8, 0
union all select '2012-09-18 09:00', 5, 2, 5, 0
union all select '2012-09-18 09:15', 10, 1, 4, 0
) as originalTable
cross join LaneData;
select Lane, max(SumCarCount) as MaxSumCarCount
from
(
select a.Lane, SUM(b.CarCount) as SumCarCount
from TrafficData a
inner join TrafficData b
on b.Lane = a.Lane
and b.StartTime between a.StartTime and DATE_ADD(DATE_ADD(a.starttime, interval 1 hour), interval -1 second)
where time(a.StartTime) between '07:00' and '08:15'
group by a.Lane, a.StartTime
) x
group by Lane
order by Lane;
select Direction, max(SumCarCount) as MaxSumCarCount
from
(
select al.Direction, SUM(b.CarCount) SumCarCount
from TrafficData a
inner join LaneData al
on al.Lane = a.Lane
inner join TrafficData b
on b.StartTime between a.StartTime and DATE_ADD(DATE_ADD(a.starttime, interval 1 hour), interval -1 second)
inner join LaneData bl
on bl.Lane = b.Lane
and bl.Direction = al.Direction
where time(a.StartTime) between '07:00' and '08:15'
group by al.Direction, a.StartTime
) x
group by Direction
order by Direction;
<强> ORIGINAL 强>
以下是我在SQL Server中的用法:
--I'd change your table structure to be like this - that way you can easily add new lanes without rewriting the whole system
declare @trafficData table
(
StartTime DateTime
,Lane int
,CarCount int
)
--here's where you store additional info about the lanes (e.g. what direction they go in)
declare @laneData table
(
Lane int
, Direction bit --0 in, 1 out
)
--populate the tables with sample data
insert @laneData
select 1, 0
union select 2, 1
union select 3, 1
union select 4, 0
insert @trafficData
select dt, lane
, case lane
when 1 then l1
when 2 then l2
when 3 then l3
when 4 then l4
else null --should never happen
end
from
(
select '2012-09-18 5:45 AM' dt, 2 l1, 0 l2, 0 l3, 0 l4
union all select '2012-09-18 6:00 AM', 1, 0, 0, 1
union all select '2012-09-18 6:15 AM', 2, 1, 0, 0
union all select '2012-09-18 6:30 AM', 2, 1, 0, 0
union all select '2012-09-18 6:45 AM', 6, 1, 2, 1
union all select '2012-09-18 7:00 AM', 9, 1, 0, 3
union all select '2012-09-18 7:15 AM', 81, 12, 22, 15
union all select '2012-09-18 7:30 AM', 144, 31, 63, 56
union all select '2012-09-18 7:45 AM', 84, 30, 62, 42
union all select '2012-09-18 8:00 AM', 7, 1, 0, 3
union all select '2012-09-18 8:15 AM', 11, 2, 3, 3
union all select '2012-09-18 8:30 AM', 12, 3, 7, 1
union all select '2012-09-18 8:45 AM', 16, 4, 8, 0
union all select '2012-09-18 9:00 AM', 5, 2, 5, 0
union all select '2012-09-18 9:15 AM', 10, 1, 4, 0
) originalTable
cross join @laneData
--peak for each individual lane
select *
from
(
select a.Lane, a.StartTime, SUM(b.CarCount) SumCarCount
, ROW_NUMBER() over (partition by a.lane order by SUM(b.CarCount) desc) r
from @trafficData a
inner join @trafficData b
on b.Lane = a.Lane
and b.StartTime between a.StartTime and DATEADD(second,-1,DATEADD(hour,1,a.starttime))
group by a.Lane, a.StartTime
) x
where r = 1
order by Lane
--peak for lane direction
select *
from
(
select al.Direction, a.StartTime, SUM(b.CarCount) SumCarCount
, ROW_NUMBER() over (partition by al.Direction order by SUM(b.CarCount) desc) r
from @trafficData a
inner join @laneData al
on al.Lane = a.Lane
inner join @trafficData b
on b.StartTime between a.StartTime and DATEADD(second,-1,DATEADD(hour,1,a.starttime))
inner join @laneData bl
on bl.Lane = b.Lane
and bl.Direction = al.Direction
group by al.Direction, a.StartTime
) x
where r = 1
order by Direction