【问题标题】:Get top n records for each group of grouped results with Bigquery (standard SQL)使用 Bigquery(标准 SQL)获取每组分组结果的前 n 条记录
【发布时间】:2017-11-24 14:46:14
【问题描述】:

我见过this question,这几乎正是我想要的。但我无法使用标准 SQL 在 Bigquery 上运行它,因为 BQ 不允许用户定义的变量。

注意 - 我有任意数量的组,因此根据链接问题中的第一个答案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  |
+--------+-------+-----+

想要的结果集:

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

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

【问题讨论】:

    标签: sql google-bigquery


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

      这是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;
      

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

      【讨论】:

        猜你喜欢
        • 2021-09-01
        • 2021-05-05
        • 1970-01-01
        • 2017-05-04
        • 1970-01-01
        • 2018-11-09
        相关资源
        最近更新 更多