繁体   English   中英

如何为每个客户在 BigQuery 中以宽格式更改 label 获取正确的最小、最大日期?

[英]How to get correct min, max date for each customer's changing label in wide format in BigQuery?

我有一个记录客户购买的表,例如:

客户ID label 日期 购买编号 价格
2 一个 2022-01-01 asd 10
3 一个 2022-01-01 自卫队 5
4 2022-02-04 asdfg 200
2 一个 2022-01-03 asdjg 4
3 2022-02-01 dfs 20
2 G 2022-04-05 fdg 40
2 G 2022-04-10 fdg 40
2 一个 2022-06-06 fgd 20

我想看看每个客户在每个 label 上花了多少天/钱,到目前为止我正在做的是:

SELECT
customer_id,
label,
COUNT(DISTINCT(purchase_id) as orders_count,
SUM(price) as total_spent,
min(date) as first_date,
max(date) as last_date,
DATE_DIFF(max(date), min(date), DAY) as days
FROM
TABLE
WHERE
date > '2022-01-01'
GROUP BY
customer_id,
label

这给了我一张长桌子,像这样:

客户ID label 订单数 总花费 第一次约会 最后日期
2 一个 3 34 2022-01-01 2022-06-06 180
2 G 1 40 2022-04-05 2022-04-10 5

ETC

为简单起见,我展示了几列,但客户一直都有订单。 上面的问题是,例如对于客户2 ,他从 label A 开始,然后更改为 G,然后他又回到 A,所以这在结果表中不可见(min(date) 是正确的,但是max(date) 采用他们的第二个 A max(date)) 并且我更喜欢宽格式。 例如,理想情况下,名为 next_label_{i} 的列对我来说是最好的,您可以为每个更改的 label 获取值。

您能否告诉我一种方法:a) 处理此 label 更改(未来 label 更改与早期标签相同)和 b) 将其制作成宽格式的方法?

谢谢

编辑:示例 output(正确日期,宽格式)[列将 go 与任何客户的唯一标签的最大数量一样宽]

客户ID 第一个标签 first_first_date first_last_date first_total_spent 第一天 下一个标签 next_first_date next_last_date next_days 下一个标签_2 next_first_date_2 next_last_date_2 next_days_2
2 一个 2022-01-01 2022-01-03 2 14 G 2022-04-05 2022-04-05 0 一个 2022-06-06 2022-06-06 0

ETC

抱歉,这并不完全准确(缺少orders_count,total_spent),但在这里格式化它很麻烦,但希望你能明白。 原则上,就好像您在之前的数据集上使用了 python 的 pivot_table。

或者,我很高兴只提供一个长格式的解决方案,该解决方案可以区分客户的 label 和同一客户的重复 label(如客户 2 以 A 开头,更改为 G 后返回 A)

您能告诉我... b) 一种将其制作成宽幅格式的方法吗?

首先,我想说我希望你有充分的理由得到 output 因为通常它不是最佳实践,而是留给表示层处理。

考虑到这一点 - 考虑以下方法

select * from (
  select customer_id, offset, purchase.*
  from (
    select customer_id, 
      array_agg((struct(label, date, purchase_id, price)) order by date) purchases
    from your_table 
    group by customer_id
  ), unnest(purchases) purchase with offset
  order by customer_id, offset
)
pivot (
  any_value(label) label, 
  any_value(date) date, 
  any_value(purchase_id) purchase_id, 
  any_value(price) price
  for offset in (0,1,2,3,4,5)
)    

如果应用于您问题中的示例数据 - output 是

在此处输入图像描述

注意:上面有一个愚蠢的假设,即您知道最大步数(在这种情况下,我使用了 6 - 从 0 到 5)。 这里有很多关于 SO 的帖子,展示了如何使用相同的技术使其动态化。 我不想复制它们,因为它违反了 SO 政策。 所以,只需在这方面做额外的功课:o)

暂无
暂无

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

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