Oracle SQL查询。如何使用“空格”作为分隔符从字符串中获取字符串标记,然后显示选择性标记?

时间:2018-09-12 08:23:20

标签: sql oracle oracle11g

例如我有一个表-USERS,列NAME1为varchar2(30)。当前其中的记录是:

NAME1:
Benjamin Barker
Alexis Jacob Alexander Cruise
Christopher James Lee

如何创建函数或编写查询以获取输出,如下所示:

Benjamin ****
Alexis **** Cruise
Christopher **** Lee 

函数/查询将计算名称字符串并返回E.g. 'Benjamin barker'作为2个令牌,但仅显示第一个令牌。而如果名称具有三个或更多标记,例如'Christopher James Lee''Alexis Jacob Alexander Cruise',它将仅显示第一个和最后一个令牌。

3 个答案:

答案 0 :(得分:1)

您可以使用instr来定位空格,并使用substr来提取标记,并具有一些条件逻辑:

-- CTE for your sample data
with users (name1) as (
            select 'Benjamin Barker' from dual
  union all select 'Alexis Jacob Alexander Cruise' from dual
  union all select 'Christopher James Lee' from dual
  union all select 'Madonna' from dual
)
-- actual query
select case
         when instr(name1, ' ') = 0
         then name1
         else substr(name1, 1, instr(name1, ' ') - 1)
       end
    || case
         when instr(name1, ' ', 1, 2) > 0
         then substr(name1, instr(name1, ' ', -1))
       end
    as result
from users;

RESULT                                                    
----------------------------------------------------------
Benjamin
Alexis Cruise
Christopher Lee
Madonna

如果您确实想要问题中显示的****,可以在第一个else子句中将其串联起来:

select case
         when instr(name1, ' ') = 0
         then name1
         else substr(name1, 1, instr(name1, ' ') - 1) || ' ****'
       end
    || case
         when instr(name1, ' ', 1, 2) > 0
         then substr(name1, instr(name1, ' ', -1))
       end
    as result
from users;

RESULT                                                         
---------------------------------------------------------------
Benjamin ****
Alexis **** Cruise
Christopher **** Lee
Madonna

或者如果您想像在评论中所说的那样添加+ Masked,仅将那些实际更改的内容添加到第三个大小写表达式中即可:

select case
         when instr(name1, ' ') = 0
         then name1
         else substr(name1, 1, instr(name1, ' ') - 1)
       end
    || case
         when instr(name1, ' ', 1, 2) > 0
         then substr(name1, instr(name1, ' ', -1))
       end
    || case
         when instr(name1, ' ', 1, 1) > 0
         then ' + Masked'
       end
    as result
from users;

RESULT                                                             
-------------------------------------------------------------------
Benjamin + Masked
Alexis Cruise + Masked
Christopher Lee + Masked
Madonna

如果要在函数中使用它,只需使用相同的大小写表达式:

create or replace function short_name (p_name varchar2)
return varchar2 as
begin
  return case
           when instr(p_name, ' ') = 0
           then p_name
           else substr(p_name, 1, instr(p_name, ' ') - 1)
         end
      || case
           when instr(p_name, ' ', 1, 2) > 0
           then substr(p_name, instr(p_name, ' ', -1))
         end
      || case
           when instr(p_name, ' ', 1, 1) > 0
           then ' + Masked'
         end;
end short_name;
/

select short_name(name1) as result from users;

RESULT                        
------------------------------
Benjamin + Masked
Alexis Cruise + Masked
Christopher Lee + Masked
Madonna

答案 1 :(得分:1)

最简单的方法是使用regexp_replace

regexp_replace(<text>,'\s+((\S+$)|(.*(\s+\S+$)))',' xxxx\4')

我不想详细说明它是如何工作的,但是您可以阅读有关regular expressions的任何指南以了解更多信息。

答案 2 :(得分:0)

create or replace function get_token 
  (in_str varchar2, in_token varchar2, in_separator varchar2 default ' ') return varchar2
as
begin
  return regexp_substr (in_str, '[^' || in_separator || ']+', 1, in_token);
end;  
/

select get_token('Christopher James Lee',1) || '****' 
         || get_token('Christopher James Lee',3) from dual;