使用 SubString 和 lpad/rpad 替换数字

Replace Digits Using SubString and lpad/rpad

有什么方法可以在 Hive 中使用子字符串替换数字。

scenario:

1. I need to check 0's from right to left and as soon as i find 0 before any digit then i need to replace all the trailing 0's by 9.
2. In output at-least 3  digit should be there before 9.
3. In Input if 2 or less digits are available in input then I need to skip some 0's and make sure that at-least 3 digits are there before 9.
4. If more than 3 digits are available before trailing 0's then only need to replace 0.No need to replace digits.

见下文table

input     output

123000    123999
120000    120999
123400    123499
101010    101019

我试过使用下面的查询,它按预期工作。(Hive Join with CTE)

with mytable as (
select '123000' as input 
union all 
select '120000' as input 
union all 
select '123400' as input 
union all 
select '101010' as input
) 
select input,lpad(concat(splitted[0], translate(splitted[1],'0','9')),6,0) as output 
from (
select input, split(regexp_replace(input,'(\d{3,}?)(0+)$','|'),'\|') splitted from mytable )s;

但是在我超过 500 行的实际查询中,很难为单个列调整此逻辑(使用 CTE)。所以想知道是否有任何方法可以仅使用 lpad/rpad 和 substring/length 来实现相同的目的,并且可以通过添加功能而不使用 CTE 查询来实现。

so let say if length of digits before trailing 0's is less than 6 then can skip the substring 
from (input,1,6) and will replace the remaining 0's and if  length of digits before trailing 0's is  6 
or more then 6 then just keep digits as it is and replace remaining trailing 0's by 9.

请多多指教。

我的实际查询看起来像。

with mytable as
(
select lpad(input,13,9) as output from mytable where code='00'
union
select output  from mytable where code='01'
)
select t1.*,m1.output from table1 t1 , mytable m1 where  
(t1.card='00' and substr(t1.low,1,13)<=m1.low and m1.output <= substr(t1.output,1,13) and m1.card='00' )
or
(t1.card='01' and substr(t1.low,1,16)<=m1.low and m1.output <=  substr(t1.output,1,16) and m1.card='01' )

我想为联合查询中代码=01 的第二个输出替换上述逻辑。

您可以使用单个查询来代替 UNION:

而不是这个

select lpad(output,13,9) as output from mytable where code='00'
union
select output  from mytable where code='01'

使用这个

select distinct
       case code when '00' then lpad(output,13,9)
                 when '01' then output  
        end output  
  from mytable 

如需过滤代码,添加where code in ('00','01')

有效Now.I 修改我的查询如下。

with mytable as
(
select lpad(input,13,9) as output from mytable where code='00'
union
select lpad(concat(split(regexp_replace('(\d{6,}?)(0+)$','|'),'\|') [0], 
translate(split(regexp_replace(input,'(\d{6,}?)(0+)$','|'),'\|')[1],'0','9')),16,0 )
output  from mytable where code='01'
)
select t1.*,m1.output from table1 t1 , mytable m1 where  
(t1.card='00' and substr(t1.low,1,13)<=m1.low 
 and m1.output <= substr(t1.output,1,13) and m1.card='00' )
 or
(t1.card='01' and substr(t1.low,1,16)<=m1.low 
and output <=  substr(output,1,16) and m1.card='01')