繁体   English   中英

使用match_recognize填写“缺失”值

[英]fill in “missing” values using match_recognize

这里的一个问题,在SO上 ,要求解决一个相当常见的用例,即填充“缺失”(基于定义的缺失标准)值与“之前”的非“缺失”值(基于定义的排序标准)行。

我通常采用的方法是解决这个问题

  • 将“丢失”值重新映射( decode / case )为NULL,
  • 对非“缺失”值使用last_value()分析函数,使用ignore nulls和所有前面行的窗口,直到定义的顺序中的当前行。

即,给出(取自原始帖子)输入行的行my_table ...

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 endcase when colX <= 0 then null else colX end为{2,3,4}的Xcase when colX <= 0 then null else colX end ),...的查询

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操作是归纳的 (基于我在查询执行计划中对SQL MODEL ORDERED操作的观察),从第一行到最后一行行中所期望排序,从而导致在该行中n具有已经填充时的行中“丢失”的值n+1正被处理。

Lukas的一条评论也提到了使用Oracle 12c的match_recognize子句的可能性。 我试图让这个(对我来说是全新的)条款理解并且工作失败了。 所以......

赏金优惠! :-)

我正在为上述问题提供最优雅的基于match_recognize的解决方案。 所有preprocessings(视图,内联的意见, with使用数据的条款,...) pivotunpivot ,自联接, model ,分析,汇总,PL / SQL,无论如何都是被禁止的。 只允许使用标准的标量SQL函数。 我对基于my_table数据源的纯match_recognize感兴趣。

我不认为你可以使用纯MATCH_RECOGNIZE子句来完成结果。 仅仅因为值col2col3col4彼此独立,但每个整行评估模式。 因此,如果可以匹配多个符号(在您的情况下多个列具有零或非零值),则仅将第一个匹配为分类器,而忽略其他符号。

对于单列,有一个简单的解决方案:

SELECT
    ORD, COL1, COL2R COL2
FROM
    my_table
MATCH_RECOGNIZE (
     ORDER BY ORD
     MEASURES
        NVL(LAST(V2.COL2), 0) AS COL2R
     ALL ROWS PER MATCH
     PATTERN ((V20*V2+V20*)+)
     DEFINE
        V2  AS  V2.COL2 > 0,
        V20 AS V20.COL2 = 0
     )

无论如何,分析函数绝对是您的最佳选择。 MODELMATCH_RECOGNIZE子句都旨在解决分析函数无法解决的不同问题,尽管优化得很好,但两者都比分析函数更重。

模式中的条件确实会按整行进行评估,因此必须为每个可能性定义条件。 然后,您可以使用SUBSET子句将适当的条件组合在一起。

WITH t(col0, col1, col2, col3, col4) AS (
  SELECT 1, 'A', 0, 1, 5 FROM DUAL UNION ALL
  SELECT 2, 'B', 0, 4, 0 FROM DUAL UNION ALL
  SELECT 3, 'C', 2, 0, 0 FROM DUAL UNION ALL
  SELECT 4, 'D', 0, 0, 0 FROM DUAL UNION ALL
  SELECT 5, 'E', 3, 5, 0 FROM DUAL UNION ALL
  SELECT 6, 'F', 0, 3, 0 FROM DUAL UNION ALL
  SELECT 7, 'G', 0, 3, 1 FROM DUAL UNION ALL
  SELECT 8, 'A', 0, 1, 5 FROM DUAL UNION ALL
  SELECT 9, 'E', 3, 5, 0 FROM DUAL
)
SELECT col0, col1, C02, C03, C04
FROM t
match_recognize(
  order by col0
  measures nvl(C02.col2,0) C02,
           nvl(C03.col3,0) C03,
           nvl(C04.col4,0) C04
  all rows per match
  pattern ((C234|C23|C24|C34|C2|C3|C4|X)+)
  subset C02 = (C234, C23, C24, C2),
         C03 = (C234, C23, C34, C3),
         C04 = (C234, C24, C34, C4)
  define C234 as col2>0 and col3>0 and col4>0,
         C23 as col2>0 and col3>0,
         C24 as col2>0 and col4>0,
         C34 as col3>0 and col4>0,
         C2 as col2>0, C3 as col3>0, C4 as col4>0
);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM