【发布时间】:2015-12-09 09:38:32
【问题描述】:
A question here, on SO,要求解决一个相当常见的用例,即用“先前”中的非“缺失”值(基于定义的排序标准)填充“缺失”(基于定义的缺失标准)值行。
我通常处理这个问题的方法是
- 将“缺失”值重新映射 (
decode/case) 为 NULL, - 对非“缺失”值使用
last_value()分析函数,并使用ignore nulls和所有前面行的窗口,直到当前行以定义的顺序排列。
即,给定一个(取自原始帖子)输入行集my_table of ...
ORD COL1 COL2 COL3 COL4
--- ---- ---- ---- ----
1 A 0 1 5
2 B 0 4 0
3 C 2 0 0
4 D 0 0 0
5 E 3 5 0
6 F 0 3 0
7 G 0 3 1
8 A 0 1 5
9 E 3 5 0
...,order by ord asc 的排序,值“缺失”的标准是该值是负数或零(case when colX <= 0 then null else colX end 用于 {2,3,4} 的 X),查询……
select X.ord, X.col1,
nvl(last_value(case when col2 > 0 then col2 end) ignore nulls over (order by ord), col2) as col2,
nvl(last_value(case when col3 > 0 then col3 end) ignore nulls over (order by ord), col3) as col3,
nvl(last_value(case when col4 > 0 then col4 end) ignore nulls over (order by ord), col4) as col4
from my_table X
order by ord;
... 会产生...的预期结果
ORD COL1 COL2 COL3 COL4
--- ---- ---- ---- ----
1 A 0 1 5
2 B 0 4 5
3 C 2 4 5
4 D 2 4 5
5 E 3 5 5
6 F 3 3 5
7 G 3 3 1
8 A 3 1 5
9 E 3 5 5
Lukas Eder 提出了一个带有model 子句的漂亮替代解决方案,在他的案例中model 操作有效inductively(基于我在他的查询执行中对SQL MODEL ORDERED 操作的观察) plan),按所需顺序从第一行到最后一行,导致n 行在处理n+1 行时已经填充了“缺失”值。
Lukas 的一个 cmets 还提到了使用 Oracle 12c 的match_recognize 子句的可能性。我试图让这个(对我来说是全新的)条款被理解并且工作失败了。所以,...
赏金优惠! :-)
我为解决上述问题的最优雅的基于match_recognize 的解决方案提供小额奖励。禁止使用pivot、unpivot、自连接、model、分析、聚合、PL/SQL 等对数据进行所有预处理(视图、内联视图、with 子句……)。只允许使用标准标量 SQL 函数。我对在基础 my_table 数据源上工作的纯 match_recognize 感兴趣。
【问题讨论】: