带有 where 子句的窗口函数(LEAD/LAG)?

Posted

技术标签:

【中文标题】带有 where 子句的窗口函数(LEAD/LAG)?【英文标题】:Window function (LEAD/LAG) with where clause? 【发布时间】:2020-01-17 23:17:01 【问题描述】:

所以我有一个网站上的页面点击表,对于特定类型的每个页面 (marketing_page),我试图识别客户点击的下一页。所以我的查询可能看起来像这样

Select * from 
(
Select page_id
, hit_time
, customer_id
, session_id
, page_type
, LEAD(page_id, 1) over (PARTITION BY customer_id, session_id ORDER BY hit_time) as next_page_id
FROM page_hits
)
WHERE page_type = 'marketing_page'

这种方法的问题是如果我将WHERE 子句保留在子查询之外,子查询就会变得巨大。理想情况下,我希望能够执行以下操作:

Select page_id
, hit_time
, customer_id
, session_id
, page_type
, LEAD(page_id, 1) over (PARTITION BY customer_id, session_id ORDER BY hit_time) as next_page_id
FROM page_hits
WHERE page_type = 'marketing_page'

但在执行LEAD 函数时,它仍会考虑WHERE 子句之外的页面。我知道LEAD 函数在WHERE 之后被评估,所以这是不可能的。

由于效率问题,我还想避免自加入。有没有一种快速/简单的方法来实现这一点?

谢谢!

【问题讨论】:

您是否遇到了特定的性能问题? SQL 是一种声明性语言,因此子查询可能不会在处理 where 之前完成评估。 这正是问题所在。在能够评估子查询之前超时。 您使用的是 Postgres 还是 Redshift?它们是非常不同的数据库(即使曾几何时代码库相似)。 对不起,应该已经澄清,使用红移 派生表对性能没有任何影响,在这种情况下,它只是语法糖。 【参考方案1】:

评论太长了。

如果一个简单的lead() 不能在 Redshift 表上工作,那可能是几件事之一。想到的是:

Redshift 数据库正忙,已用完所有查询连接,您只是在等待。我认为情况并非如此。 您的数据非常庞大。 您的“表格”确实是一个复杂的视图。

鉴于数据的性质,我会假设数据非常大。我会进一步假设它是按某个时间单位划分的,可能是天。

您需要将查询限制为一个或几个分区才能运行它。您的问题没有提供有关如何完成的信息。

【讨论】:

数据非常大。表是按天分区的,我希望一次得到一年,但也尝试了 6 个月。 @doddy 。 . .可能对数据的任何查询(不限制分区)都会超时。问题可能不是窗口函数。

以上是关于带有 where 子句的窗口函数(LEAD/LAG)?的主要内容,如果未能解决你的问题,请参考以下文章

SQL windows 函数 LEAD/LAG 但只考虑某些值?

如何不将 where 子句应用于窗口函数

带有 where 子句的 SQL MIN 函数

每个总和都带有 WHERE 子句的 SUM 函数?

通过 LEAD/LAG 或递归 CTE 更新?

具有 LEAD/LAG 功能的行到列