SQL从列中查找大写单词

时间:2018-08-01 07:09:59

标签: sql oracle

我的表格中有一个description列,其值为:

This is a EXAMPLE
This is a TEST
This is a VALUE

我只想在描述列中显示EXAMPLE,TEST和VALUE。

我该如何实现?

7 个答案:

答案 0 :(得分:12)

这可能是一种方法:

-- a test case
with test(id, str) as (
select 1, 'This is a EXAMPLE' from dual union all
select 2, 'This is a TEST' from dual union all
select 3, 'This is a VALUE' from dual union all
select 4, 'This IS aN EXAMPLE' from dual
)
-- concatenate the resulting words
select id, listagg(str, ' ') within group (order by pos)
from (
    -- tokenize the strings by using the space as a word separator
    SELECT id,
           trim(regexp_substr(str, '[^ ]+', 1, level)) str,
           level as pos           
      FROM test t
    CONNECT BY instr(str, ' ', 1, level - 1) > 0
      and prior id = id
      and prior sys_guid() is not null
    )
-- only get the uppercase words
where regexp_like(str, '^[A-Z]+$')   
group by id

这个想法是标记每个字符串,然后切掉不是由大写字母组成的单词,然后将其余单词串联起来。

结果:

1    EXAMPLE
2    TEST
3    VALUE
4    IS EXAMPLE

如果您需要将其他字符作为大写字母处理,则可以编辑where条件以过滤匹配的单词;例如,使用'_':

with test(id, str) as (
select 1, 'This is a EXAMPLE' from dual union all
select 2, 'This is a TEST' from dual union all
select 3, 'This is a VALUE' from dual union all
select 4, 'This IS aN EXAMPLE' from dual union all
select 5, 'This IS AN_EXAMPLE' from dual
)
select id, listagg(str, ' ') within group (order by pos)
from (
    SELECT id,
           trim(regexp_substr(str, '[^ ]+', 1, level)) str,
           level as pos           
      FROM test t
    CONNECT BY instr(str, ' ', 1, level - 1) > 0
      and prior id = id
      and prior sys_guid() is not null
    )
where regexp_like(str, '^[A-Z_]+$')   
group by id

给予:

1   EXAMPLE
2   TEST
3   VALUE
4   IS EXAMPLE
5   IS AN_EXAMPLE

答案 1 :(得分:4)

借助REGEXP_REPLACE函数,可以实现这一目标:

int firstMeasureId = measureIds.FirstOrDefault();
IEnumerable<int> seed = measureResults.GetFilterIds(firstMeasureId);
IEnumerable<int> restOfSequence = measureIds.Skip(1);

// the aggregate:
var result = restOfSequence.Aggregate(       // aggregate the rest of the measureIds
    seed,                                    // start with the FilterIds of the first measureId
    (previousResult, nextMeasureId) =>       // the next accumulation is
        previousResult.Intersect(            // the intersection of the previous result
           measureResults.GetFilterId(nextMeasureId) // and all FilterIds of the next measureId
     );

它使用正则表达式替换行的第一个大写字符,并用空格转换每个小写字符和空格。

答案 2 :(得分:3)

这是另一种解决方案。它的灵感来自Aleksej的回答。

这个主意?得到所有的话。然后仅将大写字母汇总到一个列表中。

样本数据:

 create table descriptions (ID int, Description varchar2(100));

 insert into descriptions (ID, Description) 
 select 1 as ID, 'foo Foo FOO bar Bar BAR' as Description from dual 
 union all select 2, 'This is an EXAMPLE TEST Description VALUE' from dual
 ;

查询:

 select id, Description, listagg(word, ',') within group (order by pos) as UpperCaseWords
 from (
     select 
      id, Description,
      trim(regexp_substr(Description, '\w+', 1, level)) as word,
      level as pos           
     from descriptions t
     connect by regexp_instr(Description, '\s+', 1, level - 1) > 0
       and prior id = id
       and prior sys_guid() is not null
     )
 where word = upper(word)
 group by id, Description

结果:

ID | DESCRIPTION                               | UPPERCASEWORDS    
-- | ----------------------------------------- | ------------------
 1 | foo Foo FOO bar Bar BAR                   | FOO,BAR           
 2 | This is an EXAMPLE TEST Description VALUE | EXAMPLE,TEST,VALUE

答案 3 :(得分:0)

尝试一下:

SELECT SUBSTR(column_name, INSTR(column_name,' ',-1) + 1)
FROM your_table;

答案 4 :(得分:0)

这应该可以解决问题:

SELECT SUBSTR(REGEXP_REPLACE(' ' || REGEXP_REPLACE(description, '(^[A-Z]|[a-z]|[A-Z][a-z]+|[,])', ''), ' +', ' '), 2, 9999) AS only_upper
FROM ( 
    select 'Hey IF you do not know IT, This IS a test of UPPERCASE and IT, with good WILL and faith, Should BE fine to be SHOWN' description
    from dual 
)

我已经添加了去除逗号的条件,您可以在内部添加其他要删除的特殊字符。

ONLY_UPPER
-----------------------------------
IF IT IS UPPERCASE IT WILL BE SHOWN

答案 5 :(得分:0)

这是一个基于某些正则表达式答案的函数。

create or replace function capwords(orig_string varchar2)
return varchar2
as
out_string varchar2(80);
begin
  out_string := REGEXP_REPLACE(orig_string, '([a-z][A-Z_]*|[A-Z_]*[a-z])', '');
  out_string := REGEXP_REPLACE(trim(out_string), '(  *)', ' ');
  return out_string;
end;
/

删除大写字母和带小写字母的下划线字符串 在任何一端。用一个空格替换多个相邻空格。 修剪两端多余的空间。假定最大大小为80个字符。

稍作编辑的输出:

>select id,str,capwords(str) from test;

        ID STR                            CAPWORDS(STR)
---------- ------------------------------ ------------------
         1 This is a EXAMPLE              EXAMPLE
         2 This is a TEST                 TEST
         3 This is a VALUE                VALUE
         4 This IS aN EXAMPLE             IS EXAMPLE
         5 This is WITH_UNDERSCORE        WITH_UNDERSCORE
         6 ThiS IS aN EXAMPLE             IS EXAMPLE
         7 thiS IS aN EXAMPLE             IS EXAMPLE
         8 This IS wiTH_UNDERSCORE        IS

答案 6 :(得分:-1)

如果只需要“显示”结果而不更改列中的值,则可以使用CASE WHEN(在示例中,Description是列名):

Select CASE WHEN Description like '%EXAMPLE%' then 'EXAMPLE' WHEN Description like '%TEST%' then 'TEST' WHEN Description like '%VALUE%' then 'VALUE' END From [yourTable]

即使全部用大写形式,条件也不区分大小写。 如果某些说明不包含任何值,则可以在Else '<Value if all conditions are wrong>'之前添加END。在这种情况下,该示例将返回NULL,而写入ELSE Description将返回该行的原始值。

如果您需要更新,它也可以使用。这是简单实用,方便的出路,哈哈。