查找Oracle DB中2列之间的值范围

时间:2017-01-12 20:04:39

标签: oracle11g

嗨,我有一个包含2列范围的表格,例如,如果范围起始= ABC1 / 000/0/0000,范围END = ABC1 / 000/0 / 1022。

我必须获取此范围之间的所有值,然后将其与另一个表连接。你能告诉我怎样才能获得DUAL表中的所有值。我正在使用Oracle 11g。

基本上我需要制作一个列表,其第一个值为ABC1 / 000/0/0000秒,为ABC1 / 000/0/0001,直到ABC1 / 000/0 / 1022.

2 个答案:

答案 0 :(得分:0)

我不知道你的意思是“暂时在DUAL中存储值”。 DUAL是一个单值的单列表!

然而,这样的事情可能就是你想要的。如果不是,那么也许你可以进一步详细说明你的问题

select blah
from another_table
where somekey in
  ( select blah
    from table
    where col between <rangeStart> and <rangeEnd>
   )

答案 1 :(得分:0)

所以,似乎你需要一些东西。

  1. 分开&#34;最后一个值&#34;从斜杠分隔的字符串,如 ABC1/000/0/0000。最好使用标准substr()和。{ instr()函数,而不是正则表达式(更快 执行)。在instr()中我们可以使用负参数 发生,表示&#34;从字符串结尾开始计算&#34;。 像这样:

    select range_from, substr(range_from, instr(range_from, '/', -1) + 1 from ...

  2. 实际上,您需要将其转换为to_number()的数字以进行进一步处理,并且您还需要将子字符串捕获到最后一个斜杠(类似于substr()的使用和instr()。您需要对range_to执行相同操作。

  3. 生成从第一个值到最后一个值的所有数字。使用connect by level查询(分层查询)可以轻松完成此操作。必须要小心,因为我们可能需要一次为多个输入行(输入范围)执行此操作。

  4. 然后将所有内容重新组合在一起,并将结果用于进一步处理。

  5. 我将假设range_from字符串至少包含一个斜杠,最后一个斜杠和字符串结尾之间的子字符串表示字符格式的非负整数,range_to类似地包含至少一个斜杠,从最后一个斜杠到字符串末尾的子字符串表示一个非负整数。您有责任保证此整数大于或等于range_from中的整数。在输出中,我将在range_from中找到最后一个斜杠使用相同的子串UP;如果要求是range_to必须具有相同的初始子字符串,那么您有责任保证这一点。

    我还假设&#34;数字的宽度(字符数)&#34; part(字符串中的最后一个标记)事先是未知的,必须在查询中计算。

    with
         test_data( id, range_from, range_to ) as (
           select 1, 'ABC1/000/0/2033', 'ABC1/000/0/2035' from dual union all
           select 2, 'xyz/33/200'     , 'xyz/33/200'      from dual union all
           select 3, '300/LMN/000'    , '300/LMN/003'     from dual
         )
    --  end of test data; SQL query begins below this line
    select id, stub || lpad(to_char(from_nbr + level - 1), len, '0') as val
    from (
       select id, stub, length(from_str) as len, to_number(from_str) as from_nbr,
                                                 to_number(to_str)   as to_nbr
       from ( 
          select id, substr(range_from, 1, instr(range_from, '/', -1))  as stub,
                     substr(range_from, instr(range_from, '/', -1) + 1) as from_str,
                     substr(range_to  , instr(range_to  , '/', -1) + 1) as to_str
          from test_data
       )
    )
    connect by level <= 1 + to_nbr - from_nbr
           and prior id = id
           and prior sys_guid() is not null
    order by id, level                               --  if needed
    ;
    
    ID VAL
    -- --------------------
     1 ABC1/000/0/2033
     1 ABC1/000/0/2034
     1 ABC1/000/0/2035
     2 xyz/33/200
     3 300/LMN/000
     3 300/LMN/001
     3 300/LMN/002
     3 300/LMN/003