提问者:小点点

使用BigQuery(标准SQL)获取每组分组结果的前n条记录


我看到了这个问题,这几乎正是我想要的。但我无法使用标准SQL处理Bigquery,因为BQ不允许用户定义变量。

注意-我有任意数量的组,所以根据链接问题中的第一个答案对所有组进行UNION是不可行的。

以下是最简单的示例,尽管任何解决方案都应该能够扩展到需要多少n个top结果:

下面的表格中有“人”、“组”和“年龄”列,您如何得到每组中最年长的两个人?(组内的关系不应产生更多结果,但应以任何顺序给出前2个结果)

+--------+-------+-----+
| Person | Group | Age |
+--------+-------+-----+
| Bob    | 1     | 32  |
| Jill   | 1     | 34  |
| Shawn  | 1     | 42  |
| Jake   | 2     | 29  |
| Paul   | 2     | 36  |
| Laura  | 2     | 39  |
+--------+-------+-----+

期望结果集:

+--------+-------+-----+
| Shawn  | 1     | 42  |
| Jill   | 1     | 34  |
| Laura  | 2     | 39  |
| Paul   | 2     | 36  |
+--------+-------+-----+

链接问题中的一个答案提到使用ROW_NUMBER,这确实存在,但是我不知道如何重新启动每个组的数字。


共2个答案

匿名用户

这是行编号()

select t.*
from (select t.*,
             row_number() over (partition by group order by age desc) as seqnum
      from t
     ) t
where seqnum <= 2;

行编号()是ANSI标准窗口函数。它在大多数数据库中都可用。一般来说,我建议您更多地使用Postgres而不是MySQL来解决BQ中的问题(如果您自己找不到BQ资源的话)。

匿名用户

可以使用有限制的ARRAY_AGG。例如,

#standardSQL
SELECT
  `Group`,
  ARRAY_AGG(STRUCT(Person, Age)
            ORDER BY Age DESC LIMIT 2) AS oldest_people
FROM People
GROUP BY `Group`;