繁体   English   中英

遍历记录并根据条件替换多个记录中的属性

[英]Iterate through records and replace attributes in multiple records based on conditions

我有以下要清理的数据。

车辆 开始 替代品
2个 一种 一种
2个 C 一种
2个 C 一种
2个 一种
2个 F 123
2个 G H 123
2个 123
2个 W X W
2个 X W
2个 Z W
3个 Q1 Q2 W
3个 Q2 Q3 W

我的目标是,每当有相同车辆的记录并且替换不是 NULL 并且有替换为 NULL 的记录(对于同一辆车)并且替换为 NULL 的记录的TO属性等于记录的FROM属性替换不是 NULL,它应该替换所有记录中的START属性,其中替换不是 NULL 并且具有上面匹配的START属性的同一车辆。

所以结果应该如下所示:

车辆 开始 替代品
2个 一种 一种
2个 C 一种
2个 C 一种
2个 一种
2个 F 一种 123
2个 G H 一种 123
2个 一种 123
2个 W X W
2个 X W
2个 Z W
3个 Q1 Q2 W
3个 Q2 Q3 W

请注意,还有其他 vehicle = 2 的条目不受影响(WZ)

我已经在带有超前和滞后的纯 SQL 中进行了很多尝试,因此我可以替换第一行(从 E 到 F),但我无法替换所有必要的行,因为没有可供我使用的标准。 所以我想没有办法绕过使用 PL/SQL 并按程序进行,但我不知道如何解决这个问题。 我可以做一些 PL/SQL,但我不是这方面的专家。

这是要使用的上表的集合。 我将不胜感激任何帮助。

WITH a AS (
SELECT 2 "vehicle", 'A' "FROM", 'B' "TO", 'A' "START", NULL "replacement" FROM dual
UNION ALL 
SELECT 2 "vehicle", 'B' "FROM", 'C' "TO", 'A' "START", NULL "replacement" FROM dual
UNION ALL 
SELECT 2 "vehicle", 'C' "FROM", 'D' "TO", 'A' "START", NULL "replacement" FROM dual
UNION ALL 
SELECT 2 "vehicle", 'D' "FROM", 'E' "TO", 'A' "START", NULL "replacement" FROM dual
UNION ALL 
SELECT 2 "vehicle", 'E' "FROM", 'F' "TO", 'E' "START", 123 "replacement" FROM dual
UNION ALL 
SELECT 2 "vehicle", 'G' "FROM", 'H' "TO", 'E' "START", 123 "replacement" FROM dual
UNION ALL 
SELECT 2 "vehicle", 'I' "FROM", 'J' "TO", 'E' "START", 123 "replacement" FROM dual
UNION ALL 
SELECT 2 "vehicle", 'W' "FROM", 'X' "TO", 'W' "START", NULL "replacement" FROM dual
UNION ALL 
SELECT 2 "vehicle", 'X' "FROM", 'Y' "TO", 'W' "START", NULL "replacement" FROM dual
UNION ALL 
SELECT 2 "vehicle", 'Y' "FROM", 'Z' "TO", 'W' "START", NULL "replacement" FROM dual
UNION ALL 
SELECT 3 "vehicle", 'Q1' "FROM", 'Q2' "TO", 'W' "START", NULL "replacement" FROM dual
UNION ALL 
SELECT 3 "vehicle", 'Q2' "FROM", 'Q3' "TO", 'W' "START", NULL "replacement" FROM dual
)
SELECT * FROM a;

您可以为此使用 match_recognize:

为了便于理解,我已将您需要的结果添加为NEW_START列。

DBFiddle: https://dbfiddle.uk/PgCeARDJ

WITH a AS (
SELECT 2 "vehicle", 'A' "FROM", 'B' "TO", 'A' "START", NULL "replacement" FROM dual
UNION ALL 
SELECT 2 "vehicle", 'B' "FROM", 'C' "TO", 'A' "START", NULL "replacement" FROM dual
UNION ALL 
SELECT 2 "vehicle", 'C' "FROM", 'D' "TO", 'A' "START", NULL "replacement" FROM dual
UNION ALL 
SELECT 2 "vehicle", 'D' "FROM", 'E' "TO", 'A' "START", NULL "replacement" FROM dual
UNION ALL 
SELECT 2 "vehicle", 'E' "FROM", 'F' "TO", 'E' "START", 123 "replacement" FROM dual
UNION ALL 
SELECT 2 "vehicle", 'G' "FROM", 'H' "TO", 'E' "START", 123 "replacement" FROM dual
UNION ALL 
SELECT 2 "vehicle", 'I' "FROM", 'J' "TO", 'E' "START", 123 "replacement" FROM dual
UNION ALL 
SELECT 2 "vehicle", 'W' "FROM", 'X' "TO", 'W' "START", NULL "replacement" FROM dual
UNION ALL 
SELECT 2 "vehicle", 'X' "FROM", 'Y' "TO", 'W' "START", NULL "replacement" FROM dual
UNION ALL 
SELECT 2 "vehicle", 'Y' "FROM", 'Z' "TO", 'W' "START", NULL "replacement" FROM dual
UNION ALL 
SELECT 3 "vehicle", 'Q1' "FROM", 'Q2' "TO", 'W' "START", NULL "replacement" FROM dual
UNION ALL 
SELECT 3 "vehicle", 'Q2' "FROM", 'Q3' "TO", 'W' "START", NULL "replacement" FROM dual
)
SELECT 
   "vehicle"
  ,"FROM"
  ,"TO"
  ,"START"
  ,"replacement"
  ,new_start,mno,cls
FROM a
match_recognize(
  partition by "vehicle"
  order by "FROM"
  MEASURES  
     A."START" as NEW_START
    ,MATCH_NUMBER() AS mno
    ,CLASSIFIER() AS cls
  ALL ROWS PER MATCH
  pattern (A (B C*)?)
  DEFINE
    B as (B."FROM" = prev(B."TO") and B."replacement" is not null and prev(B."replacement") is null),
    C as (C."replacement" is not null)
)
order by 1,2
;

在此处输入图像描述

暂无
暂无

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

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