BigQuery 中没有展平的分区

Partition without flatten in BigQuery

考虑以下架构,其中包含 transaction_no、创建日期 (created_at) 和项目 (RECORD):

[
   {
      "mode":"REQUIRED",
      "name":"Id",
      "type":"INTEGER"
   },
   {
      "fields":[
         {
            "mode":"REQUIRED",
            "name":"Name",
            "type":"STRING"
         },
         {
            "mode":"REQUIRED",
            "name":"Qty",
            "type":"INTEGER"
         }
      ],
      "mode":"REPEATED",
      "name":"Items",
      "type":"RECORD"
   },
   {
      "mode":"REQUIRED"
      "name":"Transaction_no",
      "type":"STRING"
   },
   {
      "mode":"REQUIRED",
      "name":"Created_at",
      "type":"TIMESTAMP"
   }
]

因为这个 table 再次包含相同的项目,我使用 window 函数根据 transaction_no 获取最后一个项目并按 created_at 排序,这样转储到另一个 table:

SELECT *
FROM (
  SELECT * 
  ROW_NUMBER() OVER(PARTITION BY transaction_no 
                    ORDER BY created_at DESC) as last
  FROM my_dataset.my_table
)
WHERE last = 1

不幸的是,这有以下问题。

  1. 这会拉平 Items 记录。我未选中展平结果复选框
  2. 它似乎只从每个 repeatable 记录中选取第一个字段。

我在这里要做的是在不更改 table 结构的情况下删除重复项。可能吗?

假设您的真实案例与您的示例一样简单(就架构而言)并且您有唯一的密钥来重新组合原始记录(看起来就像你确实有这样的 - transaction_no) - 最 efficient/optimal 的方法(根据我的口味)是:
1. 扁平化你的数据
2. 执行所有聚合/分组逻辑
3. 使用 NEST()
重新创建初始模式 在一个漂亮的查询中进行所有操作应该非常简单

另一种选择 - 如果您有时间进行试验 - 您可以尝试使用 OMIT … IF 子句
注意不仅可以用OMIT RECORD IF的形式,还可以用
的形式 OMIT {non-leaf node} IF。后一种形式可用于根据所需条件 OMIT Items IF condition
消除重复字段中的某些条目 您可以阅读更多关于此 https://cloud.google.com/bigquery/query-reference#omit

在你的具体情况下,我建议使用第一个选项,因为它更直接且实施起来相对简单