【问题标题】:BigQuery Standard Get first not null value when groupingBigQuery Standard 分组时获取第一个非空值
【发布时间】:2020-05-29 06:48:10
【问题描述】:

我有一张这样的桌子:

CUSTOMERS_ID  DATE_SALES  DIMENSION
MARIO1        20200201    NULL
MARIO1        20200113    Spain
MARIO2        20200131    NULL
MARIO3        20200101    France
MARIO3        20191231    Spain

我需要按 CUSTOMERS_IDDATE_SALES DESC 字段进行订购。然后我想按 CUSTOMERS_ID 字段进行分组,并首先获取 DIMENSION 字段的非空值。 输出表将是:

CUSTOMERS_ID  DIMENSION
MARIO1        Spain
MARIO2        NULL
MARIO3        France

有什么想法吗?我试过COALESCE函数,FIRST_VALUE,都没有达到我预期的结果。

提前致谢!

【问题讨论】:

    标签: google-bigquery coalesce


    【解决方案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
    

    【讨论】:

      【解决方案2】:

      以下是 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   
      

      【讨论】:

      • ARRAY_AGG 和 OFFSET 是我最好的新朋友。谢谢米哈伊尔!
      【解决方案3】:

      我们可以在这里使用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 行。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-09-04
        • 2014-05-12
        • 2012-06-24
        • 1970-01-01
        • 2013-07-03
        • 2011-02-15
        • 1970-01-01
        • 2021-06-22
        相关资源
        最近更新 更多