在SELECT
语句中,是否可以使用CASE评估Substr
?或者根据条件返回sub string
的最佳方法是什么?
我正在尝试从表的事件描述列中检索名称。事件描述列中的字符串格式为text text (Mike Smith) text text
或text text (Joe Schmit (Manager)) text text
。我想仅返回名称,但是(Manager)
之后的某些名称会丢弃我的SELECT
声明。
这是我的SELECT
声明:
SELECT *
FROM (
SELECT Substr(Substr(eventdes,Instr(eventdes,'(')+1),1,
Instr(eventdes,')') - Instr(eventdes,'(')-1)
FROM mytable
WHERE admintype = 'admin'
AND entrytime BETWEEN sysdate - (5/(24*60)) AND sysdate
AND eventdes LIKE '%action taken by%'
ORDER BY id DESC
)
WHERE ROWNUM <=1
如果没有Mike Smith
,则返回(Manager)
之类的内容,但如果有,则返回Joe Schmit (Manager
之类的内容。
非常感谢任何帮助。
答案 0 :(得分:3)
Oracle 11g R2架构设置:
CREATE TABLE MYTABLE ( id, admintype, entrytime, eventdes ) AS
SELECT 1, 'admin', SYSDATE, 'action taken by (John Doe (Manager)) more text' FROM DUAL;
查询1 :
SELECT *
FROM ( SELECT REGEXP_SUBSTR( eventdes, '\((.*?)(\s*\(.*?\))?\)', 1, 1, 'i', 1 )
FROM mytable
WHERE admintype = 'admin'
AND entrytime BETWEEN sysdate - (5/(24*60)) AND sysdate
AND eventdes LIKE '%action taken by%'
ORDER BY id DESC
)
WHERE ROWNUM <=1
<强> Results 强>:
| REGEXP_SUBSTR(EVENTDES,'\((.*?)(\S*\(.*?\))?\)',1,1,'I',1) |
|------------------------------------------------------------|
| John Doe |
修改强>
Oracle 11g R2架构设置:
CREATE TABLE MYTABLE ( id, admintype, entrytime, eventdes ) AS
SELECT 1, 'admin', SYSDATE, 'action taken by (Doe, John (Manager)) more text' FROM DUAL;
查询1 :
SELECT SUBSTR( Name, INSTR( Name, ',' ) + 1 ) || ' ' || SUBSTR( Name, 1, INSTR( Name, ',' ) - 1 ) AS Full_Name,
REGEXP_REPLACE( Name, '^(.*?),\s*(.*)$', '\2 \1' ) AS Full_Name2
FROM ( SELECT REGEXP_SUBSTR( eventdes, '\((.*?)(\s*\(.*?\))?\)', 1, 1, 'i', 1 ) AS Name
FROM mytable
WHERE admintype = 'admin'
-- AND entrytime BETWEEN sysdate - (5/(24*60)) AND sysdate
AND eventdes LIKE '%action taken by%'
ORDER BY id DESC
)
WHERE ROWNUM <=1
<强> Results 强>:
| FULL_NAME | FULL_NAME2 |
|-----------|------------|
| John Doe | John Doe |
答案 1 :(得分:1)
您可以使用INSTR搜索最后一个')',但我更喜欢正则表达式。
这将提取第一个'('和最后一个')之间的所有内容,并且TRIM删除括号(Oracle不支持在RegEx中查看):
RTRIM(LTRIM(REGEXP_SUBSTR(eventdes, '\(.*\)'), '('), ')')
答案 2 :(得分:0)
可能有一个正则表达式会在没有替换的情况下执行此操作,但我不够聪明,因此我将REGEXP_SUBSTRING替换为多个instr方法并使用REGEXP_REPLACE来替换'(MANAGER)'部分。存在。
SELECT *
FROM (
SELECT REGEXP_REPLACE(
REGEXP_SUBSTR(eventdes, '\((.*)\)', 1, 1, 'i', 1), ' \(MANAGER\)', '')
FROM mytable
WHERE admintype = 'admin'
AND entrytime BETWEEN sysdate - (5/(24*60)) AND sysdate
AND eventdes LIKE '%action taken by%'
ORDER BY id DESC
)
WHERE ROWNUM <=1
答案 3 :(得分:0)
这个问题略有不同。此正则表达式从第一个打开的paren + 1(名称的第一个字母)的位置开始,然后返回字符串中该点的第一个组,该组由1个或多个不是紧密的paren或open的字符组成括号。如果有经理,TRIM会删除尾随空格。
SQL> with tbl(id, admintype, entrytime, eventdes ) AS
2 ( SELECT 1, 'admin', SYSDATE, 'action taken by (John Doe (Manager)) more text' FROM DUAL
3 union
4 SELECT 1, 'admin', SYSDATE, 'action taken by (Jane Doe) more text' FROM DUAL
5 )
6 select trim(regexp_substr(eventdes, '([^\)\(]+)', instr(eventdes, '(')+1, 1)) name
7 from tbl;
NAME
----------------------------------------------
Jane Doe
John Doe
SQL>