从 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
我在 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