简体   繁体   English

滑动 window 上的不同计数

[英]Distinct count over a sliding window

I have 3 set of columns [date, status, customerid].我有 3 组列 [日期、状态、客户 ID]。 I need an elegant way to calculate unique customers from Tuesday to day, meaning on a Tuesday the count will include only distinct customers for that Tuesday.我需要一种优雅的方法来计算周二到一天的独特客户,这意味着在周二的计数将只包括该周二的独特客户。 On Wednesday the count includes distinct customers from Tuesday and Wednesday.周三的计数包括周二和周三的不同客户。 On a Thursday, the count should include distinct customers from Tuesday, Wednesday and Thursday.在星期四,计数应包括星期二、星期三和星期四的不同客户。 This will repeat until the following Monday and on Tuesday the cycle restarts.这将重复到下一个星期一,然后在星期二重新开始循环。 How do I approach this logic using SQL?如何使用 SQL 处理此逻辑? Also assuming count distinct over window function is not supported.还假设计数不同 window function 不受支持。

Assume this is the source假设这是源

+----------+-----------+---------+                                              
|      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|
+----------+-----------+---------+

This is the expected outcome这是预期的结果

+----------+-----------+---------+                                              
|      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|
+----------+-----------+---------+

This answers the original version of the question.这回答了问题的原始版本。

Your question has two parts.你的问题有两个部分。

One is identifying the right time frame.一是确定正确的时间范围。 In PrestoDB weeks do not begin on Tuesday.在 PrestoDB 中,周不是从星期二开始的。 I think they begin on Monday.我想他们从星期一开始。

The other is the count(distinct) .另一个是count(distinct) I think Presto supports this as a window function.我认为 Presto 支持 window function。 So, you can do:所以,你可以这样做:

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;

Note that this is phrased as a window function, not an aggregation.请注意,这被表述为 window function,而不是聚合。

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

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