在数据按 time_id 排序后,我尝试在 pagename 列上使用dense_rank() 函数。 排名列 rn 中的预期输出为:[1,2,2,3,4]。
目前我把它写成:
with tbl2 as
(select UID, pagename, date_id, time_id, source--, dense_rank() over(partition by UID order by pagename) as rn
from tbl1
order by time_id)
select *, dense_rank() over(partition by UID order by time_id, pagename) as rn
from tbl2
任何帮助将不胜感激
编辑 1:我在这里尝试实现的是根据用户屏幕上的操作流对访问的页面进行排名。假设如果在访问不同的页面 'B' 后访问同一页面 'A' 那么这些页面访问 A、B、A 的排名将是 1,2,3(注意同一页面 A 有不同的排名 1 & 3)
答案 0 :(得分:1)
SELECT
*,
SUM(is_diff) OVER (ORDER BY date_id, time_id, page)
FROM (
SELECT
*,
CASE WHEN page = lag(page) over (order by date_id, time_id) THEN 0 ELSE 1 END as is_diff
FROM mytable
)s
这看起来很像我几年前问的一个问题:Window functions: PARTITION BY one column after ORDER BY another
您想在列 (uuid, page)
上执行窗口函数,但想要保留由不相关列 (date_id, time_id)
给出的当前顺序。
问题是,PARTITION BY
在 ORDER BY
子句之前对记录进行排序。因此,它定义了主要顺序,这不是预期的。
一旦我找到了解决方案。我根据您的使用情况对其进行了调整。请阅读那边的解释:https://stackoverflow.com/a/52439794/3984221
有趣的部分:查询中没有明确要求您的特殊 rank()
情况,因为我的解决方案创建了开箱即用的(“偶然”可以这么说;))。>
答案 1 :(得分:0)
您可以像这样使用 DENSE_RANK()
来满足您的要求,
SELECT
u_id,
page_name,
date_id,
time_id,
source,
DENSE_RANK()
OVER (
PARTITION BY page_name
ORDER BY u_id DESC
) rn
FROM ( SELECT * FROM tbl1 ORDER BY time_id ) AS result;
答案 2 :(得分:0)
嗯。 . .如果您希望页面按最早时间排序,则使用两级窗口函数:
select t.*,
dense_rank() over (partition by uid order by min_rn, pagename) as ranking
from (select t.*,
min(rn) over (partition by uid, pagename) as min_rn
from t
) t
注意:这使用 rn
作为方便的快捷方式,因为日期/时间被分成两列。你也可以组合它们:
select t.*,
dense_rank() over (partition by uid order by min_dt, pagename) as ranking
from (select t.*,
min(date_id || time_id) over (partition by uid, pagename) as min_dt
from t
) t;
注意:此解决方案与 S_man 的不同。在您的样本数据上,他们做同样的事情。然而,如果用户返回到一个页面,那么他会给页面一个新的排名。这使页面的排名与其第一次出现时的排名相同。不清楚你真正想要什么。