繁体   English   中英

用于运行具有动态日期范围的不同值计数的 BigQuery

[英]BigQuery for running count of distinct values with a dynamic date-range

我们正在尝试进行查询,以获取特定年月的唯一客户总和 + 特定日期前 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                |

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

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

我们与 Google BigQuery 合作。

希望有人能帮助我们::)

这是实现您想要的结果的方法。 请注意,此查询在单独的查询中执行年月联接,并将其与滚动的 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

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

  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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM