如何在外部选择语句中使用 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 分区?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用sql语句进行分页操作?

在外部函数swift中使用表行中的indexPath

Access 选择语句中的 Row_Number()

在外部存储 Flyway 元数据表

如何在外部模块中使用 Laravel 类?

在外部循环中更新 Tkinter GUI