Oracle GROUP BY类似的时间戳?

FtD*_*Xw6 6 sql oracle group-by

我有一个活动表,其结构如下:

id  prd_id  act_dt               grp
------------------------------------
1   1       2000-01-01 00:00:00
2   1       2000-01-01 00:00:01
3   1       2000-01-01 00:00:02
4   2       2000-01-01 00:00:00
5   2       2000-01-01 00:00:01
6   2       2000-01-01 01:00:00
7   2       2000-01-01 01:00:01
8   3       2000-01-01 00:00:00
9   3       2000-01-01 00:00:01
10  3       2000-01-01 02:00:00
Run Code Online (Sandbox Code Playgroud)

我想通过product(prd_id)和activity date(act_dt)拆分此活动表中的数据,并grp使用每个组的序列中的值更新group()列.

踢球者是,我需要按类似的时间戳进行分组,其中类似的意思是"所有记录的差异恰好为1秒".换句话说,在一个组中,按日期排序的任何2条记录之间的差异恰好是1秒,并且第一条记录和最后一条记录之间的差异可以是任何时间量,只要所有中间记录都是1秒分开.

对于示例数据,组将是:

id  prd_id  act_dt               grp
------------------------------------
1   1       2000-01-01 00:00:00  1
2   1       2000-01-01 00:00:01  1
3   1       2000-01-01 00:00:02  1
4   2       2000-01-01 00:00:00  2
5   2       2000-01-01 00:00:01  2
6   2       2000-01-01 01:00:00  3
7   2       2000-01-01 01:00:01  3
8   3       2000-01-01 00:00:00  4
9   3       2000-01-01 00:00:01  4
10  3       2000-01-01 02:00:00  5
Run Code Online (Sandbox Code Playgroud)

我会用什么方法来实现这个目标?

表的大小约为2000万行,如果这会影响用于解决问题的方法.

Mat*_*lie 2

我不是 Oracle 专家,所以我猜测一行的最佳选择:

    (CAST('2010-01-01' AS DATETIME) - act_dt) * 24 * 60 * 60      AS time_id,
Run Code Online (Sandbox Code Playgroud)

这只需是“从 [aDateConstant] 到 act_dt 的秒数”。结果可能是否定的。只需要将秒数转换act_dt为 INT 即可。其余的应该可以正常工作。

WITH
  sequenced_data
AS
(
  SELECT
    ROW_NUMBER() OVER (PARTITION BY prd_id  ORDER BY act_dt)      AS sequence_id,
    (CAST('2010-01-01' AS DATETIME) - act_dt) * 24 * 60 * 60      AS time_id,
    *
  FROM
    yourTable
)
SELECT
  DENSE_RANK() OVER (PARTITION BY prd_id ORDER BY time_id - sequence_id) AS group_id,
  *
FROM
  sequenced_data 
Run Code Online (Sandbox Code Playgroud)

示例数据:

 sequence_id | time_id | t-s | group_id
-------------+---------+-----+----------
      1      |   1     |  0  |    1
      2      |   2     |  0  |    1
      3      |   3     |  0  |    1
      4      |   8     |  4  |    2
      5      |   9     |  4  |    2
      6      |   12    |  6  |    3
      7      |   14    |  7  |    4
      8      |   15    |  7  |    4
Run Code Online (Sandbox Code Playgroud)


注意:确实假设存在具有相同时间的多个记录。如果有,则需要先将其过滤掉。可能只是在前面的 CTE 中使用了 GROUP BY。