Sql 如何从历史数据中检索行程?

Sql 如何从历史数据中检索行程?,sql,hive,hiveql,Sql,Hive,Hiveql,我在Hive中有下表mytable: id radar_id car_id datetime 1 A21 123 2017-03-08 17:31:19.0 2 A21 555 2017-03-08 17:32:00.0 3 A21 777 2017-03-08 17:33:00.0 4 B15 123 2017-0

我在Hive中有下表
mytable

id    radar_id     car_id     datetime
1     A21          123        2017-03-08 17:31:19.0
2     A21          555        2017-03-08 17:32:00.0
3     A21          777        2017-03-08 17:33:00.0
4     B15          123        2017-03-08 17:35:22.0
5     B15          555        2017-03-08 17:34:05.0
5     B15          777        2017-03-08 20:50:12.0
6     A21          123        2017-03-09 11:00:00.0
7     C11          123        2017-03-09 11:10:00.0
8     A21          123        2017-03-09 11:12:00.0
9     A21          555        2017-03-09 11:12:10.0
10    B15          123        2017-03-09 11:14:00.0
11    C11          555        2017-03-09 11:20:00.0
我想得到在同一行程内通过雷达的车辆路线
A21
B15
。例如,如果同一
车辆id
的日期不同,则该行程不同。基本上,我要考虑的是,同一车辆的雷达<代码> A21和<代码> B15</代码>之间的最大时差应该是30分钟。如果更大,则行程不同,例如
汽车id
777

我的最终目标是计算每天的平均出行次数(非唯一性,因此,如果同一辆车通过同一条路线2次,则应计算2次)

预期结果如下:

radar_start   radar_end       avg_tripscount_per_day
A21           B15             1.5
在日期
2017-03-08
上,雷达
A21
B15
之间有2次行程(由于30分钟的限制,不考虑车辆
777
),而在日期
2017-03-09
上,只有1次行程。平均每天2+1=1.5次

我怎样才能得到这个结果?基本上,我不知道如何在查询中引入30分钟限制,以及如何按
radar\u start
radar\u end
对乘车进行分组

谢谢

更新:

  • 行程在开始之日登记
  • 如果车辆在2017-03-08 23:55时由雷达触发,在2017-03-09 00:15时由雷达触发,则应视为2017-03-08日登记的相同行程
  • ids
    6和8的情况下,同一辆车
    123
    经过
    A21
    两次,然后转向
    B15
    id
    10)。应考虑最后一次乘坐id为
    8的车辆。所以,
    8-10
    。因此,最接近
    B15
    的前一个。根据解释,一辆汽车经过
    A21
    两次,第二次转向
    B15

    我没有注意到您正在使用
    Hive
    ,因此开始为
    SQLServer
    编写查询,但它可能会对您有所帮助。试着这样做:

    查询

    select radar_start, 
           radar_end, 
           convert(decimal(6,3), count(*)) / convert(decimal(6,3), count(distinct dt)) as avg_tripscount_per_day
    from (
        select 
            t1.radar_id as radar_start,
            t2.radar_id as radar_end,
            convert(date, t1.[datetime]) dt,
            row_number() over (partition by t1.radar_id, t1.car_id, convert(date, t1.[datetime]) order by t1.[datetime] desc) rn1,
            row_number() over (partition by t2.radar_id, t2.car_id, convert(date, t2.[datetime]) order by t2.[datetime] desc) rn2
        from trips as t1
        join trips as t2 on t1.car_id = t2.car_id 
            and datediff(minute,t1.[datetime], t2.[datetime]) between 0 and 30
            and t1.radar_id = 'A21' 
            and t2.radar_id = 'B15'
    )x
    where rn1 = 1 and rn2 = 1
    group by radar_start, radar_end
    
    输出

    radar_start radar_end   avg_tripscount_per_day
    A21         B15         1.5000000000
    
    样本数据

    create table trips
    (
        id int,
        radar_id char(3),
        car_id int,
        [datetime] datetime
    )
    insert into trips values
    (1,'A21',123,'2017-03-08 17:31:19.0'),
    (2,'A21',555,'2017-03-08 17:32:00.0'),
    (3,'A21',777,'2017-03-08 17:33:00.0'),
    (4,'B15',123,'2017-03-08 17:35:22.0'),
    (5,'B15',555,'2017-03-08 17:34:05.0'),
    (5,'B15',777,'2017-03-08 20:50:12.0'),
    
    (6,'A21',123,'2017-03-09 11:00:00.0'),
    (7,'C11',123,'2017-03-09 11:10:00.0'),
    (8,'A21',123,'2017-03-09 11:12:00.0'),
    
    (9,'A21',555,'2017-03-09 11:12:10.0'),
    (8,'B15',123,'2017-03-09 11:14:00.0'),
    (9,'C11',555,'2017-03-09 11:20:00.0')
    

    附加说明
    如果您的版本不支持间隔,则最后的代码记录可以替换为-

    和to\u unix\u timestamp(datetime)+30*60>to\u unix\u timestamp(next\u datetime)

    @GordonLinoff:我在使用Hive。@草莓:你指的是哪种情况?以分钟为单位的最大差值应为30分钟,而不是更多。如果雷达
    A21
    B15
    之间的间隔超过30分钟(或反之亦然),则这不是同一行程,不应计算在内。然后应该忽略它。@草莓:那么,这是同一次旅行,因为相差不到30分钟。即使他们在不同的日子?@草莓:不,如果这是不同的日子,那么这是不同的旅行。在这种情况下,我认为分钟的差值为20分钟加上24小时,所以超过30分钟。谢谢!我正在测试你的查询。一个问题:在我的例子中,
    datetime
    是一个字符串。不幸的是,我无法控制DB。我只有阅读权。我应该使用
    到日期(datetime)
    ?您每天只计算一次每辆车。@Digoraius是的,看起来
    到日期(datetime)
    是Hive中内置的功能。谢谢。我收到此错误
    失败:ParseException行21:18无法识别表达式规范“”中“interval”“30”“minutes”附近的输入。我想这就是问题所在。如何将其转换为datetime?(1)这是一个经过测试的代码(2)间隔是在两年多前的Hive 1.2.0(2015年5月18日)上引入的。(3) 如果您使用字符串而不是时间戳(为什么?),而不是使用CAST(4),则始终可以将时间戳转换为unixtimeThanks。我无法控制Db。我同意把
    datetime
    作为字符串是很奇怪的。那么,我是否正确地理解了无论何时出现
    datetime
    ,我都应该用
    cast(datetime as date)
    替换它?但在本例中,我将删除time part.cast(datetime作为时间戳)
    select  count(*) / count(distinct to_date(datetime))    as trips_per_day
    
    from   (select  radar_id
                   ,datetime
                   ,lead(radar_id) over w  as next_radar_id
                   ,lead(datetime) over w  as next_datetime                    
    
            from    mytable
    
            where   radar_id in ('A21','B15')
    
            window  w as 
                    (
                        partition by  car_id
                        order by      datetime
                    )
            ) t
    
    where   radar_id        = 'A21'
        and next_radar_id   = 'B15'
        and datetime + interval '30' minutes >= next_datetime
    ;
    
    +----------------+
    | trips_per_day  |
    +----------------+
    | 1.5            |
    +----------------+