2

给定一些具有重复names 和不同s 的行,如果重复出现在第一个 45 分钟内timestamp,我想选择最新的行。timestampnametimestamp

这是在 PostgreSQL 中起作用的:

SELECT i.ts AS base_timestamp, j.ts AS newer_timestamp, i.name
FROM tbl i
LEFT JOIN LATERAL
(SELECT j.ts
 FROM tbl j
 WHERE i.name = j.name
 AND j.ts > i.ts
 AND j.ts < (i.ts + INTERVAL '45 minutes')
) j ON TRUE
WHERE j.ts is NULL

很好的解释LATERALhttps ://heap.io/blog/engineering/postgresqls-powerful-new-join-type-lateral

LATERAL join 类似于 SQL foreach 循环,其中 PostgreSQL 将遍历结果集中的每一行并使用该行作为参数评估子查询。

所以它就像一个相关的子查询,但是在连接中。

然后我只取没有更新时间戳(WHERE j.ts is NULL)的行。

如何在 BigQuery 中执行此操作?

编辑:我已经按照评论中的要求在SQLFiddle 上创建了一个 PostgreSQL 分组示例。

输入:

  ('Duplication Example','2019-06-22 19:10:25'),
  ('Duplication Example','2019-06-22 23:58:31'), 
  ('Duplication Example','2019-06-23 00:08:00')

输出(删除了时间戳 23:58:31 的中间行):

base_timestamp          newer_timestamp name
2019-06-22T19:10:25Z    (null)          Duplication Example
2019-06-23T00:08:00Z    (null)          Duplication Example
4

2 回答 2

1

您的案例看起来有点像窗口函数的任务。但是,由于您似乎对横向连接比对解决您提出的问题更感兴趣:在 BigQuery 中只有一个隐式版本的横向连接:当与未嵌套的数组连接时。

这展示了这个想法:

WITH t AS (
  SELECT 'a' as id, [2,3] as arr 
  UNION ALL SELECT 'b', [56, 7]
)

SELECT * EXCEPT(arr) 
FROM t LEFT JOIN UNNEST(arr)
于 2019-12-05T10:59:10.240 回答
1

这可以使用 WINDOW 功能存档。

SELECT
  name,
  MAX(timestamp) AS timestamp_new
FROM
(
  SELECT 
    i.name,
    COUNT(*) OVER (PARTITION BY i.name ORDER BY i.ts RANGE BETWEEN 45 * 60 * 1000 PRECEDING AND CURRENT ROW) as 45_window_count,
    i.ts AS timestamp
  FROM 
    tbl i
)
WHERE 45_window_count > 1
GROUP BY user
于 2019-12-19T09:38:15.653 回答