【问题标题】:Count distinct customers over rolling window partition通过滚动窗口分区计算不同的客户
【发布时间】:2021-01-27 06:52:08
【问题描述】:

我的问题类似于redshift: count distinct customers over window partition,但我有一个滚动窗口分区。

我的查询看起来像这样,但不支持 Redshift 中的 COUNT 不同

select p_date, seconds_read, 
count(distinct customer_id) over (order by p_date rows between unbounded preceding and current row) as total_cumulative_customer
from table_x

我的目标是计算截至每个日期的唯一身份客户总数(因此是滚动窗口)。

我尝试使用dense_rank() approach,但它会失败,因为我不能使用这样的窗口函数

select p_date, max(total_cumulative_customer) over ()
(select p_date, seconds_read, 
dense_rank() over (order by customer_id rows between unbounded preceding and current row) as total_cumulative_customer -- WILL FAIL HERE
from table_x

任何解决方法或不同的方法都会有所帮助!

编辑:

输入数据样本

+------+----------+--------------+
| Cust |  p_date  | seconds_read |
+------+----------+--------------+
|    1 | 1-Jan-20 |           10 |
|    2 | 1-Jan-20 |           20 |
|    4 | 1-Jan-20 |           30 |
|    5 | 1-Jan-20 |           40 |
|    6 | 5-Jan-20 |           50 |
|    3 | 5-Jan-20 |           60 |
|    2 | 5-Jan-20 |           70 |
|    1 | 5-Jan-20 |           80 |
|    1 | 5-Jan-20 |           90 |
|    1 | 7-Jan-20 |          100 |
|    3 | 7-Jan-20 |          110 |
|    4 | 7-Jan-20 |          120 |
|    7 | 7-Jan-20 |          130 |
+------+----------+--------------+

预期输出

+----------+--------------------------+------------------+--------------------------------------------+
|  p_date  | total_distinct_cum_cust  | sum_seconds_read |                  Comment                   |
+----------+--------------------------+------------------+--------------------------------------------+
| 1-Jan-20 |                        4 |              100 | total distinct cust = 4 i.e. 1,2,4,5       |
| 5-Jan-20 |                        6 |              450 | total distinct cust = 6 i.e. 1,2,3,4,5,6   |
| 7-Jan-20 |                        7 |              910 | total distinct cust = 6 i.e. 1,2,3,4,5,6,7 |
+----------+--------------------------+------------------+--------------------------------------------+

【问题讨论】:

  • 。 .样本数据和期望的结果会有所帮助。我不明白seconds_read的目的。
  • @GordonLinoff 添加了示例数据。读取的秒数将是累积总和

标签: sql count amazon-redshift distinct window-functions


【解决方案1】:

一种解决方法是使用子查询:

select p_date, seconds_read, 
    (
        select count(distinct t1.customer_id) 
        from table_x t1
        where t1.p_date <= t.p_date
    ) as total_cumulative_customer
from table_x t

【讨论】:

  • 我当前的表有 100B 行。你认为这种方法和count(distinct) 一样好吗? (我不是质疑你的技术,我真的不知道哪个表现更好)
  • @PirateX 您在这里没有太多选择,因为 count distinct 不能用作窗口函数。
【解决方案2】:

对于这个操作:

select p_date, seconds_read, 
       count(distinct customer_id) over (order by p_date rows between unbounded preceding and current row) as total_cumulative_customer
from table_x;

您可以使用两个级别的聚合做几乎任何您想做的事情:

select min_p_date,
       sum(count(*)) over (order by min_p_date rows between unbounded preceding and current row) as running_distinct_customers
from (select customer_id, min(p_date) as min_p_date
      from table_x
      group by customer_id
     ) c
group by min_p_date;

对读取的秒数求和有点棘手,但您可以使用相同的想法:

select p_date,
       sum(sum(seconds_read)) over (order by p_date rows between unbounded preceding and current row) as seconds_read,
       sum(sum(case when seqnum = 1 then 1 else 0 end)) over (order by p_date rows between unbounded preceding and current row) as running_distinct_customers
from (select customer_id, p_date, seconds_read,
             row_number() over (partition by customer_id order by p_date) as seqnum
      from table_x
     ) c
group by min_p_date;

【讨论】:

  • 在滚动窗口的情况下,同一用户出现在多个窗口中,是否会因为 min(p_date) 而在所有窗口中只考虑该用户一次?
  • @nescobar 。 . .用户仅在最短日期被考虑。
猜你喜欢
  • 2018-05-24
  • 2023-03-26
  • 1970-01-01
  • 2018-07-07
  • 1970-01-01
  • 2019-08-23
  • 2018-07-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多