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

jbr*_*own 2 sql google-bigquery

我已经看到了这个问题,这几乎正是我想要的。但由于BQ不允许用户定义变量,因此我无法在标准SQL的Bigquery上使用它。

注意 -我有任意数量的组,因此UNION按照链接问题中的第一个答案将所有组都放入是不可行的。

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

给定下面的表格,其中包含“人员”,“组”和“年龄”列,您将如何获得每个组中年龄最大的2个人?(组内的领带不应产生更多结果,而应以任意顺序给出前2个)

+--------+-------+-----+
| Person | Group | Age |
+--------+-------+-----+
| Bob    | 1     | 32  |
| Jill   | 1     | 34  |
| Shawn  | 1     | 42  |
| Jake   | 2     | 29  |
| Paul   | 2     | 36  |
| Laura  | 2     | 39  |
+--------+-------+-----+
Run Code Online (Sandbox Code Playgroud)

所需的结果集:

+--------+-------+-----+
| Shawn  | 1     | 42  |
| Jill   | 1     | 34  |
| Laura  | 2     | 39  |
| Paul   | 2     | 36  |
+--------+-------+-----+
Run Code Online (Sandbox Code Playgroud)

链接问题中的一个答案提到ROW_NUMBER存在使用哪个,但是我无法弄清楚如何为每个组重新编号。

Ell*_*ard 6

您可以使用ARRAY_AGG限制。例如,

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


Gor*_*off 5

这是row_number()

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

row_number()是ANSI标准窗口函数。在大多数数据库中都可用。通常,我建议您更多地使用Postgres而不是MySQL来解决BQ中的问题(如果您本身找不到BQ资源)。