首页 > 解决方案 > 在同一 cte 中返回分区的 row_num()=1

问题描述

是否有更短的方法来过滤 rown_num = 1 上的 cte 而不是外部 where 子句?我隐约记得在 teradata 中使用“qualify”语句执行此操作。我可以在 Postgres 中使用更少的代码方式吗?

with 

first_touch as (
select 
    l.session_id as last_session,
    l.client_id,
    f.session_id as first_session,
    row_number() over(partition by f.client_id order by f.date asc) as rn 
from ga_marketing.sessions l
join ga_marketing.sessions f on l.client_id = f.client_id 
where l.date between '2021-06-01' and '2021-06-11'
)

select *
from first_touch
where rn = 1

我宁愿以某种方式在 cte 内过滤 rn=1 而不是在外面。这可能吗?有没有更短的方法来写我想要的?

标签: postgresql

解决方案


您需要至少两个级别的选择才能使用 Window 函数执行此操作。如果需要,您可以在 CTE 中执行两个级别,然后在 CTE 之外进行第三个虚拟选择,但我不明白这样做的意义何在,除了让虚拟选择看起来更干净(没有 WHERE 子句,没有列“rn”)。那部分会变短,但 CTE 会变长。或者您可以完全取消 CTE 并直接编写嵌套查询,我猜这在使用的数字击键中会“更短”。或者您可以将不同的片段封装到一个视图中,以隐藏某些级别。

我认为您也可以使用 DISTINCT ON 或 JOIN LATERAL 编写此代码,而不是使用窗口函数,但这似乎不是您要问的。


推荐阅读