简体   繁体   中英

SQL to find upper case words from a column

I have a description column in my table and its values are:

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

I want to display only EXAMPLE, TEST, and VALUE from the description column.

How do I achieve this?

This could be a way:

-- 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

The idea is to tokenize every string, then cut off the words that are not made by upper case characters and then concatenate the remaining words.

The result:

1    EXAMPLE
2    TEST
3    VALUE
4    IS EXAMPLE

If you need to handle some other character as an upper case letter, you may edit the where condition to filter for the matching words; for example, with '_':

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

gives:

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

It is possible to achieve this thanks to the REGEXP_REPLACE function:

SELECT REGEXP_REPLACE(my_column, '(^[A-Z]| |[a-z][A-Z]*|[A-Z]*[a-z])', '') AS Result FROM my_table

It uses a regex which replaces first upper case char of the line and converts every lower case char and space with blanks.

Here's another solution. It was inspired by Aleksej's answer.

The idea? Get all the words. Then aggregate only fully uppercased to a list.

Sample data:

 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
 ;

Query:

 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

Result:

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

Try this:

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

This should do the trick:

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 
)

I have added condition to strip commas, you can add inside that brakets other special characters to remove.

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

This is a function based on some of the regular expression answers.

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;
/

Removes strings of upper case letters and underscores that have lower case letters on either end. Replaces multiple adjacent spaces with one space. Trims extra spaces off of the ends. Assumes max size of 80 characters.

Slightly edited output:

>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

If you only need to "display" the result without changing the values in the column then you can use CASE WHEN (in the example Description is the column name):

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

The conditions are not case sensitive even if you write it all in uppercase. You can add Else '<Value if all conditions are wrong>' before the END in case there are descriptions that don't contain any of the values. The example will return NULL for those cases, and writing ELSE Description will return the original value of that row.

It also works if you need to update. It is simple and practical, easy way out, haha.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM