Sql Oracle多重替换
我在Oracle表中有一列未清理且不一致的保修服务。例如, 在这个表中,我们有以下数据,我只想保持最高的保修期,以月为单位(如果不是以月为单位,我想转换它)。例如,从下面的第一条记录来看,18个月是最高的,我希望以月为单位保存数据,因此“保修费”将为“18”,记录#2将为“12”,而不是12,记录#6将为“24”,值将为整数: 保修主任(字符2000字节):Sql Oracle多重替换,sql,oracle,replace,Sql,Oracle,Replace,我在Oracle表中有一列未清理且不一致的保修服务。例如, 在这个表中,我们有以下数据,我只想保持最高的保修期,以月为单位(如果不是以月为单位,我想转换它)。例如,从下面的第一条记录来看,18个月是最高的,我希望以月为单位保存数据,因此“保修费”将为“18”,记录#2将为“12”,而不是12,记录#6将为“24”,值将为整数: 保修主任(字符2000字节): 记录#1:“一年18个月24周” 记录2:“12个月,8个月,60天。” 记录#3:“(30)个月。” 记录#4:“(60)个月,20周。
如何实现它,请让我知道?调试看不到的代码很困难。您说过您编写了一个存储过程,但它并不是您想要的 更换支架很简单;您可以使用嵌套的
REPLACE
s(它可以完成任务,但很难阅读和维护)或-更好的选项-TRANSLATE
:
SQL> with test (wo) as
2 (select '(60) months, [20] weeks.' from dual union all
3 select '{12} weeks, {2} years' from dual
4 )
5 select replace(replace(replace(replace(replace(replace(
6 wo, '(', ''), ')', ''), '[', ''), ']', ''), '{', ''), '}', '') result_1,
7 --
8 translate(wo, 'a()[]{}', 'a') result_2
9 from test;
RESULT_1 RESULT_2
------------------------ ------------------------
60 months, 20 weeks. 60 months, 20 weeks.
12 weeks, 2 years 12 weeks, 2 years
SQL>
你的其他问题:看起来这个过程会很长,因为你要处理很多不同的案例。循序渐进,经常测试。我不认为有魔杖解决办法
您(在评论中)询问是否可以解析这些字符串。对由于它的每一部分都用逗号隔开,因此您可以
SQL> with test (col) as
2 (select '1 year, 12 months, 18 months, 3 years, one month' from dual)
3 select trim(regexp_substr(col, '[^,]+', 1, level)) val
4 from test
5 connect by level <= regexp_count(col, ',') + 1;
VAL
------------------------------------------------
1 year
12 months
18 months
3 years
one month
SQL>
[编辑,2021年3月26日] 如果要在数字后面添加空格(如果不存在,例如将
18个月
修改为18个月
),则:
步骤2-8中使用的全局临时表仅包含相关列
- 步骤1中的替换函数比我邻居枫树中的分支要多
- 我希望我使用GTT不会加剧全球变暖!(尽管我试图把12个月的时间搞糟到24个月)
- 希望,西班牙语列查找值能提高我下次访问墨西哥时的对话技巧
欢迎任何修改代码的建议。:/p>我刚刚开始,所以我只有存储过程名称,并选择语句以删除括号。我只想保留最长的持续时间,如在结果中记录的“60个月”和“2年”。我相信只有将所有持续时间转换为月份后,这才可能实现。是否有方法遍历可以包含一个或多个逗号或不包含逗号的列字符串?为此列假设以下值=“一个月、一年、两年、12个月”。我是否可以遍历字符串并在转换后将年/年/年的任何实例替换为月?因此,一年将变为“24个月”,然后我可以再次搜索列中的最高值以仅保留最高值?嗯,“一年”应变为“12个月”(而不是“24个月”),至少在我住的地方。你能做你描述的吗?当然,那叫解析。我在答案的末尾添加了一些信息;看一看。谢谢你的帮助。这看起来像是基于列值中逗号数的水平轴。下面是
SQL> with test (id, col) as
2 (select 1, '1 year, 12 months, 18 months, 3 years, one month' from dual union all
3 select 2, 'twelve months, 8 months, 60 days.' from dual
4 )
5 select id,
6 trim(regexp_substr(col, '[^,]+', 1, column_value)) val
7 from test cross join
8 table(cast(multiset(select level from dual
9 connect by level <= regexp_count(col, ',') + 1
10 ) as sys.odcinumberlist))
11 order by id, column_value;
ID VAL
---------- ------------------------------------------------
1 1 year
1 12 months
1 18 months
1 3 years
1 one month
2 twelve months
2 8 months
2 60 days.
8 rows selected.
SQL>
SQL> with
2 test (col) as
3 (select 'one year, 18months, 24 weeks' from dual),
4 temp as
5 -- split it to rows (you already know how to do that)
6 (select trim(regexp_substr(col, '[^,]+', 1, level)) val
7 from test
8 connect by level <= regexp_count(col, ',') + 1
9 )
10 -- in CASE, check whether VAL contains a space. If so, return VAL. If not,
11 -- add a space after digits
12 select
13 val,
14 case when instr(val, ' ') = 0 then regexp_replace(val, '(\d+)', '\1 ')
15 else val
16 end new_val
17 from temp;
VAL NEW_VAL
---------- ----------
one year one year
18months 18 months
24 weeks 24 weeks
SQL>
SQL> with test (col) as
2 (select 1 from dual union all
3 select 18 from dual union all
4 select 24 from dual union all
5 select 673 from dual
6 )
7 select col,
8 to_char(to_date(col, 'j'),'jsp') in_words
9 from test;
COL IN_WORDS
---------- ---------------------------------------------------
1 one
18 eighteen
24 twenty-four
673 six hundred seventy-three
SQL>