我有一个HIVE表,如下所示:
device metric timestamp value
d_1 cpu_time 2020-08-15 00:05:00 10
d_1 cpu_time 2020-08-15 00:10:00 12
d_1 cpu_time 2020-08-15 00:15:00 08
d_2 cpu_time 2020-08-15 00:05:00 62
d_2 cpu_time 2020-08-15 00:10:00 14
d_2 cpu_time 2020-08-15 00:15:00 10
d_3 cpu_time 2020-08-15 00:05:00 12
d_3 cpu_time 2020-08-15 00:10:00 44
d_3 cpu_time 2020-08-15 00:15:00 60
因此,对于每个不同的设备,时间窗口显示10秒(05:00至15:00(。这意味着,当数据中遇到新设备时,3个时间戳的集合会重复。
实际的HIVE表有大约1200万行,数千个设备,每个设备的总时间窗口为26天(而不是示例表中显示的10秒(。此外,时间戳之间的采样间隔为5秒(就像上面的示例表一样(。因此,实际表中的模式与示例表中的相同,只是更多的数据。
我运行以下查询来确定每个度量的采样间隔(预计为5分钟(:
select
metric,
(unix_timestamp(timestamp) - unix_timestamp(lag_ts)) / 60 sampling_interval_minutes,
count(*) no_hits
from (
select
t.*,
lag(timestamp) over(partition by metric order by timestamp) lag_ts
from my_table t
) t
group by metric, (unix_timestamp(timestamp) - unix_timestamp(lag_ts)) / 60
order by metric, no_hits desc
它为真实的HIVE表提供这样的输出:
metric sampling_interval_minutes no_hits
cpu_time 0.0 11976480
cpu_time 5.0 7486
cpu_time 1445.0 1
cpu_time NULL 1
第二行显示了预期输出,因为实际HIVE表中的时间窗口为26天,即7488个5分钟的观测值(上面有7486个,但忽略了这一差异(。
令人惊讶的结果显然是第一排,显示11976480支安打,0落后。这几乎是HIVE表中的所有行。我假设这意味着,由于时间窗口(26天(重复,这些差异在时间戳之间被视为0。但我本以为滞后不关心重复,而只是给出数据中遇到的行之间的差异。换句话说,我预计会有大约1200万个滞后,间隔5分钟。这是因为实际表中大约有1600个不同的设备,它们都有26天的时间窗口(7488个不同的5分钟间隔(,1600 x 7488大约是1200万。
SQL中的滞后是否使用排列或组合,而不仅仅是逐行评估时间戳的差异?
I认为您希望每个设备的计算,因此您应该使用:
lag(timestamp) over (partition by metric, device order by timestamp) as lag_ts
关于此声明:
但我本以为滞后不关心重复,而只是给出数据中遇到的行之间的差异。
您的期望值不适合SQL数据库。SQL表表示无序的集合。lag()
所知道的关于排序和分区的一切都在lag()
表达式本身中。