我如何找到车辆的峰值数量和高峰时间

时间:2016-10-26 16:37:32

标签: sql sql-server-2008

我有一张包含公共交通记录的表格。我需要知道高峰车辆出行的时间和车辆数量。 日期范围是一个会计年度,从7/1 / yyyy到6/30 / yyyy。 我的表名为fixedrouterecords,这是相关列的示例。

我尝试过为峰值用户使用一些示例,但无法实现。

service_date    bus leave_yard  return_to_yard
 2016-10-24     104  05:15:00    06:30:00
 2016-10-24     204  04:10:00    06:30:00

当然,一个会计年度有数千行

6 个答案:

答案 0 :(得分:2)

这将按服务日生成峰值时间

Declare @YourTable table (service_date date,bus int,leave_yard Time,return_to_yard time)
Insert Into @YourTable values
('2016-10-24',104,'05:15:00','06:30:00'),
('2016-10-24',204,'04:10:00','06:30:00'),
('2016-10-25',997,'05:15:00','06:30:00'),
('2016-10-25',998,'04:10:00','06:30:00'),
('2016-10-25',999,'05:30:00','06:00:00'),
('2016-10-26',999,'06:30:00','07:15:00')

;with cte0(N) as (Select 1 From (Values(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) N(N))
    , cteT(T) as (Select Top 1440 cast(DateAdd(MI,Row_Number() over (Order By (Select NULL))-1,'1900-01-01') as time) From cte0 N1, cte0 N2, cte0 N3, cte0 N4) 
    , cteBase as (
         Select service_date
               ,bus
               ,OutTime = T
         From   @YourTable A
         Join   cteT B
         on     T between leave_yard and return_to_yard
         Where  Year(service_date)=2016  -- or any other filter you like  
      )
Select A.Service_Date
      ,A.MinOut 
      ,A.MaxOut 
      ,Busses = count(Distinct B.Bus)
 From (
        Select Service_Date
              ,MinOut = Min(A.OutTime)
              ,MaxOut = Max(A.OutTime)
         From (
                Select *,Rnk=Rank() over (Partition By Service_Date Order by Hits Desc)
                 From (Select Service_Date,OutTime,Hits=count(*) From cteBase Group by Service_Date,OutTime ) A
               ) A 
         Where Rnk=1
         Group By Service_Date
      ) A
 Join cteBase B on A.Service_Date=B.Service_Date and B.OutTime between A.MinOut and A.MaxOut
 Group By A.Service_Date,A.MinOut,A.MaxOut 

按服务日显示PEAK使用情况

Service_Date    MinOut   MaxOut    Busses
2016-10-24     05:15:00  06:30:00  2
2016-10-25     05:30:00  06:00:00  3
2016-10-26     06:30:00  07:15:00  1

答案 1 :(得分:1)

select      service_date
           ,vehicles_out
           ,ts              as from_time
           ,next_ts         as to_time

from       (select      t.*
                       ,rank () over (partition by service_date order by vehicles_out desc) as rnk

            from       (select      service_date
                                   ,ts
                                   ,sum  (op) over (partition by service_date order by ts,op,bus)   as vehicles_out
                                   ,lead (ts) over (partition by service_date order by ts,op,bus)   as next_ts

                        from        (           select service_date ,bus ,leave_yard     as ts , 1 as op from fixedrouterecords 
                                    union all   select service_date ,bus ,return_to_yard       ,-1       from fixedrouterecords 
                                    ) t
                        ) t
            ) t

where       rnk = 1
;

答案 2 :(得分:1)

  

编辑 - 删除了对UDF的需求并添加了一个临时记录

Declare @YourTable table (service_date date,bus int,leave_yard Time,return_to_yard time)
Insert Into @YourTable values
('2016-10-24',104,'05:15:00','06:30:00'),
('2016-10-24',204,'04:10:00','06:30:00')

;with cte0(N) As (Select 1 From (Values(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) N(N))
    , cteT(T) As (Select Top 1440 cast(DateAdd(MI,Row_Number() over (Order By (Select NULL))-1,'1900-01-01') as time) From cte0 N1, cte0 N2, cte0 N3, cte0 N4) 
    , cteBase as (
         Select service_date
               ,bus
               ,OutTime = T
         From   @YourTable A             -- << Replace with Your Table Name
         Join   cteT B
         on     T between leave_yard and return_to_yard
         Where  Year(service_date)=2016  -- << Or any other filter you like  
      )
Select MinOut 
      ,MaxOut
      ,Busses = count(Distinct bus)
 From (
        Select Top 1 
               Hits
              ,MinOut=min(OutTime)
              ,MaxOut=max(OutTime)
         From  (Select OutTime,Hits=count(*) from cteBase group by OutTime) A
         Group By Hits
         Order By Hits Desc
       ) A
 Join cteBase B on (OutTime between MinOut and MaxOut)
 Group By MinOut,MaxOut

返回

MinOut      MaxOut      Busses
05:15:00    06:30:00    2

答案 3 :(得分:0)

这可能不是最好的方法,但我认为应该有效。假设你有一个24小时的窗口(基于有限的信息)我会使用视图或CTE并为持续时间和一天中的每个小时创建一列(即01,02,03等)

然后我会使用leave_yard + Duration来确定公共汽车出发当天的时间(即填充01值的公式)

 Case WHEN leave_yard > 01:00 AND leave_yard < (leave_yard + duration) THEN '1' ELSE '0' END AS '01'

因此,您将当天的每小时列设置为1或0,然后将小时数相加,这样您就可以获得每天每小时的公交车数量。然后将小时与另一个表达式进行比较,并使用聚合等进行汇总

答案 4 :(得分:0)

SELECT phour AS peak_hour,
       bus_cnt AS peak_count
  FROM
     (
       SELECT *,
              ROW_NUMBER() OVER ( ORDER BY bus_cnt DESC ) AS rnk       
         FROM 
            (
               SELECT cast( DATEPART( hour, leave_yard ) as varchar )+ ':00:00' AS phour,
                      COUNT( bus ) AS bus_cnt 
                 FROM fixedrouterecords
                GROUP BY phour
             ) A
    ) B

WHERE rnk = 1     ;

答案 5 :(得分:0)

SELECT phour AS peak_hour, bus_cnt AS peak_count FROM ( SELECT *, ROW_NUMBER() OVER ( ORDER BY bus_cnt DESC ,partition by bus_cnt ) AS rnk
FROM ( SELECT cast( DATEPART( hour, leave_yard ) as varchar )+ ':00:00' AS phour, COUNT( bus ) AS bus_cnt FROM fixedrouterecords GROUP BY cast( DATEPART( hour, leave_yard ) )y )z WHERE z.rnk = 1;