Oracle SQL-如何找到所需字符串的所有可能位置而没有发生特定情况

时间:2019-02-28 05:29:45

标签: sql oracle

我们知道INSTR()仅返回一个数字
例如哈利·波特
如果我们使用INSTR(“ Harry Potter”,“”)来找到空间的位置,我们将从这个函数中得到'6'吗?但是,如果我想知道所有可能的空格位置,该如何修改此条件(或使用其他函数就可以了)

例如列名“电影”包含电影名称,电影名称之间可以有任意空格,例如
  《指环王》,《奥创纪元》,......

如何找到所有空间位置并假设我们之前不了解所有数据,所以无法解决该列中出现的空间。

             Thanks guys,

3 个答案:

答案 0 :(得分:1)

这里是一个选择:

SQL> with test (movies) as
  2    (select 'The Lord Of The Ring' from dual union all
  3     select 'Age Of ultron' from dual
  4    )
  5  select movies,
  6         instr(movies, ' ', 1, column_value) space_position
  7  from test,
  8       table(cast(multiset(select level
  9                           from dual
 10                           connect by level <= regexp_count(movies, ' ')
 11                          ) as sys.odcinumberlist))
 12  order by movies, space_position;

MOVIES               SPACE_POSITION
-------------------- --------------
Age Of ultron                     4
Age Of ultron                     7
The Lord Of The Ring              4
The Lord Of The Ring              9
The Lord Of The Ring             12
The Lord Of The Ring             16

6 rows selected.

SQL>

答案 1 :(得分:1)

尝试创建包含数字的varray类型。比创建非默认函数来获取所有空格。您必须具有适当的特权。

-- SOLUTION

-- create varray type
-- it contains max 20 numeric elements
create or replace type array_n is varray(20) of number;

-- this function gets string and returns array of numbers
-- numbers show spaces in the text
create or replace function getspaces(fname varchar2) return array_n  is
    arr array_n; -- arr variable is array_n type
begin
    -- check, if the text length is longet than 0 (if text is not null)
    if length(fname) is null then return null;
    end if;

    arr := array_n(); -- itialize varray

    -- iterate for each letter in text
    for i in 1..length(fname) loop
        -- if leter is space, extend array and save it's position
        if substr(fname,i,i+1) = ' ' then
            arr.extend; -- Extend it
            arr(arr.count + 1) := i;
        end if;
    end loop;

    return arr; -- return array
end;
/

-- TEST ON SYNTHETIC DATA
create table films (
    id integer constraint film_id primary key,
    name varchar2(30)
);
insert into films values(1, 'The Lord of the Boats');
insert into films values(2, 'All Possible solutions');
insert into films values(3, 'I love you guys');
insert into films values(4, null);


select f.*, getspaces(f.name) from films f;

答案 2 :(得分:0)

这是与Littlefoot几乎相同的另一种方式

 WITH a AS 
 (
 SELECT 'The Lord Of The RingAge Of Ultron' as n from dual UNION ALL
SELECT 'This is a movie name' from dual
 )
,b as (
SELECT a.* ,length(n)-length(replace(n,' ','')) o
FROM a
  ) 
 , c as (
 Select distinct  b.*
 ,level le
  from b connect by level < o
order by n
   )
 Select n
 , instr(n,' ',1,le ) occur
  from c