【问题标题】:Distinct count over a sliding window滑动窗口上的不同计数
【发布时间】:2020-10-10 13:47:43
【问题描述】:

我有 3 组列 [日期、状态、客户 ID]。我需要一种优雅的方法来计算周二到一天的独特客户,这意味着在周二的计数将只包括该周二的独特客户。周三的计数包括周二和周三的不同客户。在星期四,计数应包括星期二、星期三和星期四的不同客户。这将重复到下一个星期一,然后在星期二重新开始循环。如何使用 SQL 处理此逻辑?还假设不支持 count distinct over window 函数。

假设这是来源

+----------+-----------+---------+                                              
|      date|customer_id|   status|
+----------+-----------+---------+
|2020-06-08|        001|AVAILABLE|
|2020-06-08|        001|  EXPIRED|
|2020-06-08|        001|AVAILABLE|
|2020-06-08|        002|AVAILABLE|
|2020-06-08|        002|  EXPIRED|
|2020-06-08|        003|  EXPIRED|
|2020-06-08|        003|AVAILABLE|
|2020-06-09|        001|AVAILABLE|
|2020-06-09|        001|AVAILABLE|
|2020-06-09|        002|  EXPIRED|
|2020-06-09|        003|AVAILABLE|
|2020-06-09|        003|  EXPIRED|
|2020-06-09|        003|  EXPIRED|
|2020-06-10|        001|  EXPIRED|
|2020-06-10|        001|  EXPIRED|
|2020-06-10|        001|AVAILABLE|
|2020-06-10|        001|AVAILABLE|
|2020-06-10|        002|AVAILABLE|
|2020-06-10|        002|AVAILABLE|
|2020-06-10|        002|  EXPIRED|
|2020-06-10|        002|AVAILABLE|
|2020-06-10|        002|  EXPIRED|
|2020-06-10|        003|  EXPIRED|
|2020-06-10|        003|AVAILABLE|
|2020-06-10|        003|AVAILABLE|
|2020-06-11|        001|  EXPIRED|
|2020-06-11|        001|  EXPIRED|
|2020-06-12|        001|AVAILABLE|
|2020-06-12|        001|  EXPIRED|
|2020-06-12|        003|  EXPIRED|
|2020-06-12|        003|AVAILABLE|
|2020-06-12|        004|AVAILABLE|
|2020-06-13|        001|AVAILABLE|
|2020-06-13|        002|AVAILABLE|
|2020-06-13|        002|AVAILABLE|
|2020-06-13|        002|AVAILABLE|
|2020-06-14|        001|  EXPIRED|
|2020-06-14|        003|  EXPIRED|
|2020-06-14|        004|  EXPIRED|
|2020-06-15|        001|  EXPIRED|
|2020-06-15|        001|AVAILABLE|
|2020-06-15|        001|  EXPIRED|
|2020-06-15|        003|  EXPIRED|
|2020-06-15|        003|AVAILABLE|
|2020-06-16|        001|AVAILABLE|
|2020-06-16|        001|  EXPIRED|
|2020-06-16|        002|AVAILABLE|
|2020-06-16|        002|AVAILABLE|
|2020-06-16|        002|  EXPIRED|
|2020-06-16|        002|  EXPIRED|
|2020-06-16|        003|  EXPIRED|
+----------+-----------+---------+

这是预期的结果

+----------+-----------+---------+                                              
|      date|      count|   status|
+----------+-----------+---------+
|2020-06-08|       NULL|     NULL|
|2020-06-09|          2|AVAILABLE|
|2020-06-09|          2|  EXPIRED|
|2020-06-10|          3|  EXPIRED|
|2020-06-10|          3|AVAILABLE|
|2020-06-11|          3|AVAILABLE|
|2020-06-11|          3|  EXPIRED|
|2020-06-12|          4|AVAILABLE|
|2020-06-12|          3|  EXPIRED|
|2020-06-13|          4|AVAILABLE|
|2020-06-14|          4|  EXPIRED|
|2020-06-15|          4|  EXPIRED|
|2020-06-15|          4|AVAILABLE|
|2020-06-16|          3|  EXPIRED|
|2020-06-16|          2|AVAILABLE|
+----------+-----------+---------+

【问题讨论】:

  • 请提供样本数据和期望的结果。

标签: sql apache-spark-sql presto


【解决方案1】:

这回答了问题的原始版本。

您的问题分为两部分。

一个是确定正确的时间范围。在 PrestoDB 中,周不是从星期二开始的。我想他们从星期一开始。

另一个是count(distinct)。我认为 Presto 支持这个作为窗口函数。所以,你可以这样做:

select distinct date,
       count(distinct user_id) over (partition by date_trunc('week', date - interval '1 day')
                                     order by date
                                    ) as unique_users_since_tuesday
from t;

请注意,这被表述为窗口函数,而不是聚合。

【讨论】:

  • 我也想看看没有count(distinct)的解决方案。我仍在考虑在 presto 或 spark sql 上应用,而后者不支持在窗口函数内区分计数。
  • 在上面的查询中,如果我必须添加状态列,查询会是什么样子?
  • @Ram。 . .那么在我看来,你会有一个不同的问题,应该作为一个新问题提出,并提供清晰的解释、示例数据和期望的结果。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-01
  • 1970-01-01
  • 2018-08-27
  • 2018-02-02
  • 2013-01-15
  • 2023-03-25
相关资源
最近更新 更多