雪花窗函数 last_value 和 max

Posted

技术标签:

【中文标题】雪花窗函数 last_value 和 max【英文标题】:Snowflake window function last_value and max 【发布时间】:2021-03-18 02:18:06 【问题描述】:

我有一张这样的桌子:

我想为每个 user_key 获取每个日期/月/工作日/周的 top total_listened

我想我需要使用窗口函数 我可以得到不同的日期格式:

MONTH(stream_date) for months
WEEKDAY(stream_date) for weekday
WEEK(stream_date) for week

我试过这个:

select 
MAX(vals.total_listened_per_day) as RECORD_STREAM_DAY_TIME,
MAX(vals.total_listened_per_month) as RECORD_STREAM_MONTH_TIME,
MAX(vals.total_listened_per_week) as RECORD_STREAM_WEEK_TIME,
MAX(vals.most_active_weekday) as MOST_ACTIVE_WEEKDAY_TIME
 last_value(days.date) over (partition by user_key order by days.total_listened) as RECORD_STREAMDAY,
from
(
select user_key, stream_date as date,
sum(st.length_listened) over (partition by user_key, stream_date) as total_listened_per_day,
sum(st.length_listened) over (partition by user_key, MONTH(stream_date)) as total_listened_per_month,
sum(st.length_listened) over (partition by user_key, WEEK(stream_date)) as total_listened_per_week,
sum(st.length_listened) over (partition by user_key, DAYNAME(stream_date)) as most_active_weekday
group by 1,2
 .....
 )

用于获取金额(以_TIME为结尾的变量),但不适用于获取特定的日期/月份....(末尾没有_TIME的变量,例如RECORD_STREAMDAY),这是因为group by ,它是按 stream_date 而不是按 month(stream_date) 分组的,例如,我不知道如何在没有 doin 子查询的情况下做到这一点

【问题讨论】:

【参考方案1】:

我认为你想要的逻辑是:

select user_key,
    max(total_listened_per_day  ) as max_total_listened_per_day
    max(total_listened_per_week ) as max_total_listened_per_week,
    max(total_listened_per_month) as max_total_listened_per_month,
    max(case when rn_day   = 1 then date_trunc('day',   stream_date) end) as most_active_day,
    max(case when rn_week  = 1 then date_trunc('week',  stream_date) end) as most_active_week,
    max(case when rn_month = 1 then date_trunc('month', stream_date) end) as most_active_month
from (  
    select t.*,
        rank() over(partition by user_key order by total_listened_per_day   desc) as rn_day,
        rank() over(partition by user_key order by total_listened_per_week  desc) as rn_week,
        rank() over(partition by user_key order by total_listened_per_month desc) as rn_month
    from (
        select t.*
            sum(st.length_listened) over (partition by user_key, date_trunc('day',   stream_date)) as total_listened_per_day,
            sum(st.length_listened) over (partition by user_key, date_trunc('week',  stream_date)) as total_listened_per_week
            sum(st.length_listened) over (partition by user_key, date_trunc('month', stream_date)) as total_listened_per_month
        from mytable t
    ) t
) t
group by user_key

最内部的子查询计算每天、每周和每月的收听时间的窗口总和。下一个子查询使用该信息对记录进行排名。最后,外部查询使用条件聚合来带来相应的持续时间和周期。如果有平局,则选择最近的时期。

【讨论】:

我认为它有效,在最后一个范围内我认为您的意思是选择 st.* 而不是 t.* 对吗?我有点理解背后的逻辑,你应用一个带有等级的数字来识别它,但是如何仅仅通过按目标排序就可以说这个是每天?另外我还有另一个与这个问题无关的问题,我想用百分比排名最高,这里只使用按 desc 排序的 total_listened 并说这些客户在听众的前 5%、前 10%、顶部20% 等等 你知道怎么做吗? (我看到了一个函数排名百分比,但我不能让它这样工作......) @echo55:查询中没有st(所有子查询都别名为t)。是的,查询为每一行附加了一个排名,因此我们可以使用条件max() 隔离相应的日期。至于您的其他问题,可能值得一个新问题,提供适当的样本数据、期望的结果和逻辑解释。

以上是关于雪花窗函数 last_value 和 max的主要内容,如果未能解决你的问题,请参考以下文章

雪花仓库:MAX WH 尺寸可以封顶吗?

同构雪花

雪花函数中的 DDL 语句

雪花 - 如何使用函数显示列名?

使用雪花连接器和 COPY INTO 功能将 csv 上传到雪花时如何指定分隔符

如何在雪花中使用 SQL 用户定义函数?