0

我们有一个交通计数器,以 15 分钟为增量对每条车道(两个进站和两个出站)的汽车进行计数。

有一个高峰期,定义为上午 7:00 至上午 9:00。在这个高峰期,我们想知道PeakHourInPeakHourOut以及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

任何帮助将不胜感激。

4

2 回答 2

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
于 2013-10-21T23:40:03.260 回答
0

编辑

这是 MySQL 中的一个解决方案:http ://sqlfiddle.com/#!2/ff0fb/9

创建表 TrafficData ( StartTime timestamp
,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;

原来的

以下是我在 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
于 2013-10-22T00:01:34.280 回答