从 BigQuery 中的数组中删除重复项

Remove duplicates from an array in BigQuery

我在 BigQuery 中工作,我的 table 之一有一个数组,其中有重复项,我想弄清楚如何删除。我能够使用 CTE 识别问题行,但实际上删除它们是我遇到的问题。

让我举个例子来提供更多背景信息:

Order Item.Sku Item.Quantity Item.Price Shipment.Ship_Number
123 ABC 2 5.99 UPS123
ABC 2 5.99 UPS234
XYZ 1 19.99
456 ABC 2 5.99 UPS456
789 XYZ 1 19.99 UPS789

因此查看此 table(对于代码,将其称为 Order_Table),我只想删除订单 123 的项目数组中的第二个“行”- 因为sku、数量、价格都一模一样。 456号订单和789号订单虽然在Item数组中的信息相同,但由于订单号不同,所以不认为是重复的。我还包含了一个额外的数组,Shipment,因为我正在处理一个包含多个数组的 table,所以我想确保任何解决方案都考虑到了这一点。所以在重复删除之后,我想这样结束:

Order Item.Sku Item.Quantity Item.Price Shipment.Ship_Number
123 ABC 2 5.99 UPS123
XYZ 1 19.99 UPS234
456 ABC 2 5.99 UPS456
789 XYZ 1 19.99 UPS789

知道如何到达那里吗?如果您有任何问题,请随时提出,我很乐意提供更多背景信息。谢谢!

编辑:这就是我使用 CTE 识别问题行的方式:

select * from
(select item.*
,row_number() over (
  partition by 
    order,
    item.sku,
    item.quantity,
    item.price
  order by item.sku)
    as row_id
    from Order_Table t, t.Item item)
  where row_id > 1

如果您想在 BigQuery 中对数组进行重复数据删除,1) 首先必须展平数组。 2) 随后,重复数据删除可以照常进行(例如使用不同或分组等) 3) 最后,对于 return 一个数组(作为原始模式),我们可以在主键上分组并使用 ARRAY_AGG.

1) 使用 UNNEST 运算符对数组进行展平。

The UNNEST operator takes an ARRAY and returns a table, with one row for each element in the ARRAY.

结合CROSS JOIN,我们为每个数组记录检索一行。 (注意,逗号表示 CROSS JOIN,参见 docs

SELECT 
  order_id,
  item.sku AS item_sku,
  item.price AS item_price
FROM data, UNNEST(items) AS item

2) 使用 DISTINCT 我们检索唯一记录。

SELECT DISTINCT
  order_id,
  item.sku AS item_sku,
  item.price AS item_price
FROM data, UNNEST(items) AS item

3) 我们可以对主键 (order_id) 进行分组,并使用 ARRAY_AGG 到 return 结果作为数组。即,returning 原始模式。

SELECT 
  order_id,
  ARRAY_AGG(
    STRUCT(
      item_sku AS sku,
      item_price AS price
    ) 
  ) AS item
FROM flattened
GROUP BY order_id


完整的可重现示例

WITH data AS (
  SELECT 
    123 AS order_id,
    [
      STRUCT(
        'ABC' AS sku,
        5.99 AS price
      ),
      STRUCT(
        'ABC' AS sku,
        5.99 AS price
      ),
      STRUCT(
        'XYZ' AS sku,
        19.99 AS price
      )
    ] AS items,
  
  UNION ALL
  
  SELECT 
    456, 
    [
      STRUCT(
        'ABC' AS sku,
        5.99 AS price
      )
    ]
    
  UNION ALL
  
  SELECT 
    789, 
    [
      STRUCT(
        'XYZ' AS sku,
        19.99 AS price
      )
    ]
),

flattened AS (
  SELECT DISTINCT
    order_id,
    item.sku AS item_sku,
    item.price AS item_price
  FROM data, UNNEST(items) AS item
)

SELECT 
  order_id,
  ARRAY_AGG(
    STRUCT(
      item_sku AS sku,
      item_price AS price
    ) 
  ) AS item
FROM flattened
GROUP BY order_id