【问题标题】:BigQuery for running count of distinct values with a dynamic date-rangeBigQuery 用于运行具有动态日期范围的不同值的计数
【发布时间】:2022-02-14 19:25:52
【问题描述】:

我们正在尝试进行查询,以获取特定年份月份的唯一身份客户总数 + 特定日期前 364 天的唯一身份客户总数。

例如

我们的客户表如下所示:

| order_date   | customer_unique_id |
| --------     | --------------     |
| 2020-01-01   | tom@email.com      |
| 2020-01-01   | daisy@email.com    |
| 2019-05-02   | tom@email.com      |

在此示例中,我们有两位客户在 2020 年 1 月 1 日订购,其中一位已在 364 天的时间范围内订购。

所需的表格应如下所示:

| year_month | unique_customers |
| --------   | --------------   |
| 2020-01    | 2                |

我们尝试了多种解决方案,例如分区和窗口,但似乎都无法正常工作。棘手的部分是独特性。我们想要 364 天前的外观,但想要基于整个期间而不是基于日期/年/月对客户进行不同的计数,因为那样我们会得到重复。例如,如果您按日期、年份或月份进行分区,tom@email.com 将被计算两次而不是一次。

此查询的目标是深入了解 12 个月内的订单频率(订单除以客户)。

我们使用 Google BigQuery。

希望有人可以帮助我们! :)

【问题讨论】:

    标签: sql google-bigquery


    【解决方案1】:

    这是实现您想要的结果的一种方法。请注意,此查询在单独的查询中进行年月联接,并将其与滚动的 364 天间隔查询联接。

    with year_month_distincts as (
        select  
            concat(
               cast(extract(year from order_date) as string), 
               '-', 
               cast(extract(month from order_date) as string)
            ) as year_month,
            count(distinct customer_id) as ym_distincts
        from customer_table
        group by 1
    )
    
    select x.order_date, x.ytd_distincts, y.ym_distincts from (
        select 
           a. order_date,
           (select 
               count(distinct customer_id) 
            from customer_table b 
            where b.order_date between date_sub(a.order_date, interval 364 day) and a.order_date 
           ) as ytd_distincts 
        from orders a
        group by 1
    ) x
    join year_month_distincts y on concat(
       cast(extract(year from x.order_date) as string), 
       '-', 
       cast(extract(month from x.order_date) as string)
    ) = y.year_month
    

    【讨论】:

      【解决方案2】:

      使用数组的两个选项可能会有所帮助。

      1. 按要求回顾 364 天
      2. 如果您希望回顾 11 个月(假设报告是每月)
      month_array AS (
        SELECT 
         DATE_TRUNC(order_date,month) AS order_month,
        STRING_AGG(DISTINCT customer_unique_id) AS cust_mth
        FROM customer_table
        GROUP BY 1
      ), 
      
      year_array AS (
        SELECT
          order_month, 
         STRING_AGG(cust_mth) OVER(ORDER by UNIX_DATE(order_month) RANGE BETWEEN 364 PRECEDING AND CURRENT ROW) cust_12m
      -- (option 2) STRING_AGG(cust_mth) OVER (ORDER by cast(format_date('%Y%m', order_month) as int64) RANGE BETWEEN 99 PRECEDING AND CURRENT ROW) AS cust_12m
      FROM month_array
      )
      
      SELECT format_date('%Y-%m',order_month) year_month,  
        (SELECT COUNT(DISTINCT cust_unique_id) FROM UNNEST(SPLIT(cust_12m)) AS cust_unique_id) as unique_12m
      FROM year_array
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-11-19
        • 1970-01-01
        • 1970-01-01
        • 2012-05-19
        • 2020-07-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多