基于值的时间序列对表中的值进行排名

时间:2018-02-06 19:17:31

标签: sql sql-server

我有一张类似于这张的桌子,代表哪些司机在某些时候驾驶不同的车。

CAR_ID    DRIVER_ID    DT
  10          A      10:00
  10          A      12:00
  10          A      14:00
  10          B      16:00
  10          B      17:00
  10          B      20:00
  10          A      21:00
  10          A      22:00
  20          C      15:00
  20          C      18:00

DT是日期时间。我尝试使用DENSE_RANK()函数获得类似的内容,但在两个驱动程序之间的列DRIVER_ID上发生更改时生成新数字。这将是我的预期输出:

CAR_ID    DRIVER_ID    DT    RES
  10          A      10:00    1
  10          A      12:00    1
  10          A      14:00    1
  10          B      16:00    2
  10          B      17:00    2
  10          B      20:00    2
  10          A      21:00    3    # 
  10          A      22:00    3    # 
  20          C      15:00    4
  20          C      18:00    4

使用DENSE_RANK() OVER (PARTITION BY CAR_ID, DRIVER_ID ORDER BY DT) AS RES我得到标有#的两个元素作为前三行的同一组成员,但我希望它们不同,因为"不连续" (这辆车是由另一名司机从16:00到20:00驾驶的)。我似乎无法找到一个不包含循环的解决方案。这可能吗?

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:2)

可以使用select t.*,sum(case when prev_driver = driver then 0 else 1 end) over(partition by id order by dt) as res from (select t.*,lag(driver_id) over(partition by id order by dt) as prev_driver from tbl ) t 并运行总和来完成此操作。

{{1}}

答案 1 :(得分:1)

你需要做一个按行划分的row_number并按dt命令。你还需要做一个由汽车和司机分区的row_number,并按dt排序。从第一个中减去第二个数字会给你一个独特的“分段”数字 - 在这种情况下,它代表每个车手每辆车的持续持有时间。

此段号值没有内在含义 - 只保证汽车和司机分区内的每个段都不同。然后使用此段号作为您尝试应用的任何功能的附加分区。

但是,作为一个注释,我无法弄清楚你如何从你引用的代码中得到RES显示的结果,因此我不确定你想要实现的是什么整体。