根据TimeStamp选择BigQuery中最近的N条记录 - 更优化

问题描述

我想根据时间戳列选择最新的 2 条记录,比如说进行分析。 实际上,我有庞大的数据集,我想为每个 user_n 选择 n 条记录。

如果我可以对值进行硬编码,那就没问题了。

SELECT * 
FROM
  `project-id`.huge-dataset-id.streaming-data`
WHERE timestamp_column BETWEEN '2015-06-10 14:20' AND '2015-06-10 14:30'

但它必须是动态制定的。我在 sql 和 BigQyery 方面不是那么强。请帮忙。

我需要最新的 N 条记录

尝试过 -(工作解决方案),需要更优化的解决方案。

SELECT *
  FROM (
    SELECT *
    FROM `project-id`.`dataset`.`streaming_data` s1
    WHERE (
        SELECT COUNT(*)
        FROM `project-id`.`dataset`.`streaming_data` s2
        WHERE s1.user_n = s2.user_n
            AND s1.timestamp_col <= s2.timestamp_col
    ) <= 2
  ) 

由于嵌套查询太多,操作真的很慢。 有人可以提供优化的解决方案吗。

数据表为 streaming_data

-------------------------------
| user_n  | timestamp_column  |
|-----------------------------|
| ABC     | 10-Jun-12 14.30   |
| DEF     | 10-Jun-12 14.30   |
| ABC     | 10-Jun-12 14.20   |
| DEF     | 10-Jun-12 14.20   |
| ABC     | 10-Jun-12 14.10   |
| DEF     | 10-Jun-12 14.10   |
| ABC     | 10-Jun-12 14.00   |
| DEF     | 10-Jun-12 14.00   |

预期输出:所有用户的最新 2 条记录,基于最新时间戳

-------------------------------
| user_n  | timestamp_column  |
|-----------------------------|
| ABC     | 10-Jun-12 14.30   |
| DEF     | 10-Jun-12 14.30   |
| ABC     | 10-Jun-12 14.20   |
| DEF     | 10-Jun-12 14.20   |

解决方法

使用row_number()。例如,要获取最近的记录:

SELECT sd.* EXCEPT (seqnum)
FROM (SELECT sd.*,ROW_NUMBER() OVER (PARTITION BY user_n ORDER BY timestamp_column DESC) as seqnum
      FROM `project-id`.huge-dataset-id.streaming-data` sd
      WHERE timestamp_column BETWEEN '2015-06-10 14:20' AND '2015-06-10 14:30'
     ) sd
WHERE seqnum <= 2;

如果您想要两个随机行,请改用 ORDER BY rand()

包含时间戳范围是因为这是问题所在。但是,要获取最近的两行,您可以将其删除。