使用 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')
有什么方法可以在 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')