BigQuery Standard 分组时首先获取非空值
BigQuery Standard Get first not null value when grouping
我有一个 table 这样的:
CUSTOMERS_ID DATE_SALES DIMENSION
MARIO1 20200201 NULL
MARIO1 20200113 Spain
MARIO2 20200131 NULL
MARIO3 20200101 France
MARIO3 20191231 Spain
我需要按 CUSTOMERS_ID 和 DATE_SALES DESC 字段进行排序。然后我想按 CUSTOMERS_ID 字段分组,并首先获得 DIMENSION 字段的非空值。
输出 table 将是:
CUSTOMERS_ID DIMENSION
MARIO1 Spain
MARIO2 NULL
MARIO3 France
有什么想法吗?我已经尝试了 COALESCE
个函数,FIRST_VALUE
,但我没有得到预期的结果。
提前致谢!
我们可以在这里使用 ROW_NUMBER
技巧:
WITH cte AS (
SELECT CUSTOMERS_ID,
ROW_NUMBER() OVER (PARTITION BY CUSTOMERS_ID
ORDER BY -1.0*UNIX_SECONDS(DATE_SALES) DESC) rn
FROM yourTable
)
SELECT CUSTOMERS_ID, DIMENSION
FROM cte
WHERE rn = 1
ORDER BY CUSTOMERS_ID;
逻辑是按纪元以来的负秒数对行号 降序 进行排序。这会将最近的销售放在第一位,并将 NULL
放在最后,因此如果没有非 NULL
维度数据可用,NULL
值将仅接收行号 1。
您可以按客户 ID 分组并通过忽略 NULLS 使用 ARRAY_AGG,您还可以在该字段中按日期排序。
限制 1 将通过使用更少的 RAM 存储来提高效率。
然后,OFFSET(0) 将使其成为一个未嵌套的字段,因此您可以轻松地使用该字段。
WITH
raw_data AS
(
SELECT 'MARIO1' CUSTOMERS_ID, 20200201 DATE_SALES, NULL as DIMENSION UNION ALL
SELECT 'MARIO1' CUSTOMERS_ID, 20200113 DATE_SALES, 'Spain' as DIMENSION UNION ALL
SELECT 'MARIO2' CUSTOMERS_ID, 20200131 DATE_SALES, NULL as DIMENSION UNION ALL
SELECT 'MARIO3' CUSTOMERS_ID, 20200101 DATE_SALES, 'France' as DIMENSION UNION ALL
SELECT 'MARIO3' CUSTOMERS_ID, 20191231 DATE_SALES, 'Spain' as DIMENSION
)
SELECT CUSTOMERS_ID, ARRAY_AGG(DIMENSION IGNORE NULLS ORDER BY DATE_SALES DESC LIMIT 1)[OFFSET(0)] as DIMENSION
FROM raw_data
GROUP BY 1
以下适用于 BigQuery 标准 SQL
#standardSQL
SELECT AS VALUE ARRAY_AGG(t ORDER BY IF(DIMENSION IS NULL, NULL, DATE_SALES) DESC LIMIT 1)[OFFSET(0)]
FROM `project.dataset.table` t
GROUP BY CUSTOMERS_ID
如果应用于您问题中的示例数据 - 结果是
Row CUSTOMERS_ID DATE_SALES DIMENSION
1 MARIO1 20200113 Spain
2 MARIO2 20200131 null
3 MARIO3 20200101 France
我有一个 table 这样的:
CUSTOMERS_ID DATE_SALES DIMENSION
MARIO1 20200201 NULL
MARIO1 20200113 Spain
MARIO2 20200131 NULL
MARIO3 20200101 France
MARIO3 20191231 Spain
我需要按 CUSTOMERS_ID 和 DATE_SALES DESC 字段进行排序。然后我想按 CUSTOMERS_ID 字段分组,并首先获得 DIMENSION 字段的非空值。 输出 table 将是:
CUSTOMERS_ID DIMENSION
MARIO1 Spain
MARIO2 NULL
MARIO3 France
有什么想法吗?我已经尝试了 COALESCE
个函数,FIRST_VALUE
,但我没有得到预期的结果。
提前致谢!
我们可以在这里使用 ROW_NUMBER
技巧:
WITH cte AS (
SELECT CUSTOMERS_ID,
ROW_NUMBER() OVER (PARTITION BY CUSTOMERS_ID
ORDER BY -1.0*UNIX_SECONDS(DATE_SALES) DESC) rn
FROM yourTable
)
SELECT CUSTOMERS_ID, DIMENSION
FROM cte
WHERE rn = 1
ORDER BY CUSTOMERS_ID;
逻辑是按纪元以来的负秒数对行号 降序 进行排序。这会将最近的销售放在第一位,并将 NULL
放在最后,因此如果没有非 NULL
维度数据可用,NULL
值将仅接收行号 1。
您可以按客户 ID 分组并通过忽略 NULLS 使用 ARRAY_AGG,您还可以在该字段中按日期排序。 限制 1 将通过使用更少的 RAM 存储来提高效率。 然后,OFFSET(0) 将使其成为一个未嵌套的字段,因此您可以轻松地使用该字段。
WITH
raw_data AS
(
SELECT 'MARIO1' CUSTOMERS_ID, 20200201 DATE_SALES, NULL as DIMENSION UNION ALL
SELECT 'MARIO1' CUSTOMERS_ID, 20200113 DATE_SALES, 'Spain' as DIMENSION UNION ALL
SELECT 'MARIO2' CUSTOMERS_ID, 20200131 DATE_SALES, NULL as DIMENSION UNION ALL
SELECT 'MARIO3' CUSTOMERS_ID, 20200101 DATE_SALES, 'France' as DIMENSION UNION ALL
SELECT 'MARIO3' CUSTOMERS_ID, 20191231 DATE_SALES, 'Spain' as DIMENSION
)
SELECT CUSTOMERS_ID, ARRAY_AGG(DIMENSION IGNORE NULLS ORDER BY DATE_SALES DESC LIMIT 1)[OFFSET(0)] as DIMENSION
FROM raw_data
GROUP BY 1
以下适用于 BigQuery 标准 SQL
#standardSQL
SELECT AS VALUE ARRAY_AGG(t ORDER BY IF(DIMENSION IS NULL, NULL, DATE_SALES) DESC LIMIT 1)[OFFSET(0)]
FROM `project.dataset.table` t
GROUP BY CUSTOMERS_ID
如果应用于您问题中的示例数据 - 结果是
Row CUSTOMERS_ID DATE_SALES DIMENSION
1 MARIO1 20200113 Spain
2 MARIO2 20200131 null
3 MARIO3 20200101 France