我有一个活动表,其结构如下:
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
我想按产品(prd_id
)和活动日期(act_dt
)拆分此活动表中的数据,并使用以下值更新组(grp
)列每个组的序列。
踢球者是,我需要通过类似的时间戳进行分组,其中类似的意思是“所有记录的差异恰好为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
我会用什么方法来实现这个目标?
如果这会影响用于解决问题的方法,那么表的大小约为2000万行。
答案 0 :(得分:2)
我不是Oracle的头衔,所以我猜测一行的最佳选择:
(CAST('2010-01-01' AS DATETIME) - act_dt) * 24 * 60 * 60 AS time_id,
这只需要是“从[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
示例数据:
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
注意:此 假设 不 多条记录具有相同的时间。如果存在,则需要先将其过滤掉。可能只是在前面的CTE中使用GROUP BY。