在 SQL 表上查找每个参与者的速度

问题描述

我有一个关于几个人的运动的 sql 表 (people_movement),如下所示:

姓名 时间 位置增量(m)
布列塔尼 10.20 -75
布列塔尼 10.30 800
布列塔尼 10.45 800
布列塔尼 11.00 900
艾伦 10.15 400
艾伦 10.16 -700
艾伦 1020 800
凯西 9.50 800
凯西 10.01 -400
凯西 10.05 200

注意是记录了时间,所以对于第一条记录,开始时间未知,但是以一行的时间作为下一行的开始时间。 有数以千计的参与者有不同的行数,有些参与者有 4 或 5 行,但许多参与者有 100 行。 我需要计算他们的移动速度(米/分钟),所以表格看起来像这样:

姓名 开始时间 结束时间 位置增量(m) 增量速度(米/分钟)
布列塔尼 - 10.20 -75 -
布列塔尼 10.20 10.30 800 80
布列塔尼 10.30 11.45 800 53.33
布列塔尼 10.45 11.00 900 60
艾伦 - 10.15 400 -
艾伦 10.15 10.16 -700 -700
艾伦 10.16 10.20 800 200
凯西 - 09.50 800 -
凯西 09.50 10.01 -400 -0.18
凯西 10.01 10.05 200 50

注意增量速度只是(位置增量/(开始时间 - 结束时间)),其中结束时间只是每个参与者(姓名)下一次移动的时间。

有没有办法进行这样的计算?

谢谢

解决方法

使用自连接。

CREATE TABLE speed_test(name varchar(10),time int,position int);
mysql> INSERT INTO speed_test VALUES ('Brittany',1020,-75);
Query OK,1 row affected (0,01 sec)

mysql> INSERT INTO speed_test VALUES ('Brittany',1030,800);
Query OK,00 sec)

mysql> INSERT INTO speed_test VALUES ('Brittany',1045,1100,900);
Query OK,00 sec)

mysql> INSERT INTO speed_test VALUES ('Alan',1015,400);
Query OK,1016,-700);
Query OK,01 sec)

mysql> INSERT INTO speed_test VALUES ('Alan',800);

   SELECT t1.name,t2.time as start_time,t1.time as end_time,t1.position,t1.position/(t1.time-t2.time) 
    FROM speed_test t1 
    LEFT JOIN 
    speed_test t2
    ON t2.name=t1.name 
       AND t2.time<t1.time 
       AND t2.time=(SELECT max(time) FROM  speed_test WHERE t1.name=name AND time<t1.time);

+----------+------------+----------+----------+-------------------------------+
| name     | start_time | end_time | position | t1.position/(t1.time-t2.time) |
+----------+------------+----------+----------+-------------------------------+
| Brittany |       NULL |     1020 |      -75 |                          NULL |
| Brittany |       1020 |     1030 |      800 |                       80.0000 |
| Brittany |       1030 |     1045 |      800 |                       53.3333 |
| Brittany |       1045 |     1100 |      900 |                       16.3636 |
| Alan     |       NULL |     1015 |      400 |                          NULL |
| Alan     |       1015 |     1016 |     -700 |                     -700.0000 |
| Alan     |       1016 |     1020 |      800 |                      200.0000 |
+----------+------------+----------+----------+-------------------------------+

速度的差异是因为时间列中的整数与时间。

,

由于您的 TimeFormat 是 HH.mm,您需要分别捕捉小时和分钟。

如果您使用的是 SQL Server,请尝试以下操作:

Create table #temp
(
 Name varchar(100),Time numeric(6,2),Position_Increment int
)
INSERT INTO #temp
values
('Brittany',10.20,-75 ),('Brittany',10.30,800 ),10.45,11.00,900 ),('Alan',10.15,400 ),10.16,-700),('Casey',9.50,10.01,-400),10.05,200 )



;with cte as 
(
      select Name,Time as EndTime,Position_Increment,Lag(EndTimeHH,1,0) over (partition by Name order by Time ) as StartTimeHH,Lag(EndTimemm,0) over (partition by Name order by Time ) as StartTimemm,StartTime,EndTimeHH,EndTimemm
      from
      (
         select *,SUBSTRING(cast(time as varchar),CHARINDEX('.',time)-1) as EndTimeHH,time)+1,len(time)) as EndTimemm,Lag(Time,0) over (partition by Name order by Time ) as StartTime
         from #temp
      ) as t
)

select Name,CASE WHEN StartTime =0 Then '-' ELSE CAST(StartTime AS varchar) END AS StartTime,EndTime,CASE WHEN StartTime =0 
            Then '-' 
            ELSE CAST(Position_Increment /ABS(((StartTimeHH*60+StartTimemm) - (EndTimeHH*60+EndTimemm))) AS varchar)
       END AS IncrementSpeed
from cte
order by name
 
Drop table #temp
,

以下伪代码解释了要做什么:

select name,lag(time) over (partition by name order by time) as start_time,time as end_time,( position_increment /
         (time - lag(time) over (partition by name order by time))
       ) as increment_speed
from t;

一个警告是日期/时间函数在数据库中变化很大,因此您需要使用适当的逻辑来减去两次。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...