Oracle中的子字符串和字符串计算

时间:2018-12-08 05:52:20

标签: sql oracle

我正在尝试使用substring和instring根据条件提取所需的值。

如果manager_name列以'Express door%'或'Express Door%'(D用大写字母开头)

,我需要一个特定的部分

by 之后

提取2条记录的值,并从 by 之后且','

之前提取1条记录

示例代码:

CREATE TABLE [Test](
service_id int,
category_id int,
employee_name varchar(50)
)

insert into Test values (38756,201830,'kalyan');
insert into Test values (38366,201790,'kalyan');
insert into Test values (38756,201830,'kalyan');
insert into Test values (38366,201790,'kalyan');
insert into Test values (38603,201790,'Ricky');


CREATE TABLE [major](
spec_id int,
manager_name varchar(150)
)

insert into major values (38756,null)
insert into major values (38366,null)
insert into major values (38756,'Express Door for on going : DECLINE by kalyan')
insert into major values (38366,'Express door for on going : APPROVE by Joy kalyan')
insert into major values (38366,'Request required')
insert into major values (38603,'Express door for on going : APPROVE by JRicky, Condtion:test')

在我正在使用的SQL查询下面:

    select  distinct 
         t.service_id
        ,m.spec_id
       , t.category_id
       , t.employee_name
       , substr(m.manager_name , instr(m.manager_name , 'by') + 3) Manager       
from test t 
left outer join major m on t.service_id = m.spec_id 
where (instr(m.manager_name, 'Express Door') > 0 or instr(m.manager_name, 'Express door') > 0);

我的期望应该如下所示:

service_id   category_id       employee_name     manager
38366           201790          kalyan           Joy kalyan
38756           201830          kalyan           kalyan
38603           201790          Ricky            JRicky

预先感谢

Swetha J

1 个答案:

答案 0 :(得分:1)

您必须确定索引',',并将匹配单词的长度作为测试方案的第三个参数传递。

此外,我使用WHERE函数和INITCAP

简化了LIKE子句
SELECT DISTINCT t.service_id,
                m.spec_id,
                t.category_id,
                t.employee_name,
                substr(m.manager_name,instr(m.manager_name,'by') + 3,
                    CASE
                     WHEN m.manager_name LIKE '%,%' 
                        THEN instr(m.manager_name,',') 
                                           - (instr(m.manager_name,'by') + 3)
                          ELSE length(m.manager_name)
                                          - (instr(m.manager_name,'by') + 2)
                     END
                ) AS manager
FROM test t
LEFT OUTER JOIN major m ON t.service_id = m.spec_id
WHERE initcap(m.manager_name) LIKE '%Express Door%'
ORDER BY employee_name;

如您所见,使用纯INSTRSUBSTR可以匹配多个模式,从而使它变得有点混乱。 尽管效率可能较低,但我们可以使用REGEXP_SUBSTR对其进行简化。

select  distinct 
         t.service_id
        ,m.spec_id
       , t.category_id
       , t.employee_name
       , REGEXP_SUBSTR(manager_name,'by(.*?)(,|$)',1,1,null,1) as  manager
from test t 
left outer join major m on t.service_id = m.spec_id 
where initcap(m.manager_name) like  '%Express Door%'
ORDER by employee_name;

by(.*?)(,|$)-在找到逗号或行尾之前,先匹配by,再匹配一组单词(名称)。 .*?用于非贪婪匹配。

Demo