oracle SQL获取前一行最新匹配条件的值

3j86kqsm  于 2023-06-05  发布在  Oracle
关注(0)|答案(1)|浏览(217)

我有一个CTE,其中的列看起来像这个表:

create table example (
rn int, --generated row number
id int,
start_value int,
end_value int,
starts_chunk int --1 starts a new chunk, 0 means the chunk is continued
);

我想添加另一列chunk_start_value,它包含当前块的start_value
以下内容

select *
, (select start_value
   from example em
   where rn = (
     select max(rn))
     from example ei
     where rn <= eo.rn
     and starts_chunk = 1
   )
  ) chunk_start_value
from example eo

对于DBMS来说,嵌套循环太多,无法处理,因为example CTE中大约有400k行。
我不能有一个自引用窗口函数来做这件事(这是我在Excel中所做的):

select *
, case
    when starts_chunk = 1 then start_value
    else lag(chunk_start_value) over (order by rn)
  end chunk_start_value
from example

我不能将任何中间结果具体化到临时表中,否则我会对开始块的行进行具体化并对其进行索引。
我可以在SQL中做我需要做的事情吗?

vh0rcniy

vh0rcniy1#

您可以使用case表达式作为参数,并使用ignore nulls分析函数的加法来跳过作为块的延续的值:

select
  e.*
  , last_value(decode(starts_chunk, 1, rn)) ignore nulls
      over(order by rn) as start_chunk_rn
from example e
order by rn asc

| RN| ID|开始值|END_VALUE| STARTS_CHUNK|开始_组块_RN|
| - -----|- -----|- -----|- -----|- -----|- -----|
| 1| 1| 3| 5个|1| 1|
| 2| 2| 1|八|0| 1|
| 3| 3| 4| 1| 0| 1|
| 4| 4|八|5个|0| 1|
| 5个|5个|1|六|0| 1|
| 六|六|4| 3| 1|六|
| 七个|七个|4|八|0|六|
| 八|八|5个|六|0|六|
| 九个|九个|2|七个|0|六|
| 十个|十个|2|八|0|六|
| 十一|十一|5个|5个|1|十一|
| 十二岁|十二岁|3| 5个|0|十一|
| 十三|十三|九个|六|0|十一|
| 十四|十四|六|5个|0|十一|
| 十五|十五|3|九个|0|十一|
| 十六|十六|5个|2| 1|十六|
| 十七岁|十七岁|九个|3| 0|十六|
| 十八岁|十八岁|1| 2| 0|十六|
| 十九|十九|2|九个|0|十六|
fiddle

相关问题