如何在外部选择语句中使用 row_number 分区?
Posted
技术标签:
【中文标题】如何在外部选择语句中使用 row_number 分区?【英文标题】:How can I use row_number over partition in outer select statement? 【发布时间】:2014-11-26 18:59:18 【问题描述】:我有一个类似的查询:
select a.id,
a.date,
-- case statements using h.fields
from advr a,
(select id,
date,
advr_id,
advr_nbr,
row_number() over(partition by id, date order by advr_nbr) adv_number
from advr_hist) h
where a.id = h.id
and a.date = h.date
group by a.id, a.date
我的许多案例陈述的一个例子:
max(case
when h.adv_number = 1 then
h.advr_id
else
' '
end) advr_1
这很好用,但加载速度很慢。如果我删除h
表中的case 语句和,一切都很快。如果我只是查询h
select 语句,一切都很快。然而加入它们会使其运行非常缓慢,因此我考虑将其作为一种视图进行重新设计。
如何从 select 语句中获得相同的结果,但在外部 select 语句中有 row_number() adv_number
字段?希望这是有道理的。
【问题讨论】:
您是否尝试过预过滤 adv_number = 1 的h
表并与 a
表进行左连接?
也许您应该比较两个查询的查询执行计划以发现关键差异?
它应该没有任何区别,如果你使用它,你必须以某种方式付费。 “快速”是指快速选择前几行还是取回所有数据?
【参考方案1】:
with result (id,date,_id)
as (
select id,date,
case when row_number() over(partition by id, date order by advr_nbr)=1
then 1 else 0 end as [_id]
from advr_hist)
select id,date from result
where _id=1
【讨论】:
欢迎来到 ***!将代码放入答案时,您可以按“代码格式化”按钮来保留代码的间距,而不是将其作为一个大的连续行。【参考方案2】:您尚未发布任何执行计划。您也没有试图解释您的查询试图做什么。所以我们能做的就是猜测。
我的猜测是,您只需要子查询中最早行的详细信息。您当前的实现使用聚合来执行此操作,这将产生各种各样的 CPU 周期。所以问题可能不是加入,而是子查询的过滤。
在这种情况下,您可以简单地这样做:
select a.id,
a.date,
h.advr_id as advr_1
from advr a,
(select id,
date,
advr_id,
advr_nbr,
row_number() over(partition by id, date order by advr_nbr) adv_number
from advr_hist) h
where a.id = h.id
and a.date = h.date
and h.adv_number = 1
如果这没有产生您想要的结果,您需要编辑您的问题并提供更多详细信息。
“所以我考虑将其重新设计为一个视图。”
视图是一种便利而非性能增强。
【讨论】:
以上是关于如何在外部选择语句中使用 row_number 分区?的主要内容,如果未能解决你的问题,请参考以下文章