繁体   English   中英

SQL SELECT如何在两列之间查找子字符串号?

[英]SQL SELECT How to find a substring number in between two columns?

给定一个搜索字符串(部分数字)和一个具有两个varchar列FROM_NUMBER和TO_NUMBER的表,我想选择包含搜索字符串的行,该字符串的数字介于FROM_NUMBER和TO_NUMBER(含)之间。

我知道像'%xxx%',但这仅用于匹配列。

示例:我有下表NUMBER_RANGE

| ID | PREFIX | FROM_NUMBER | TO_NUMBER  |
|----|--------|-------------|------------|
| 1  | +1     | 4081234500  | 4081234599 |
| 2  | +61    | 267222000   | 267222009  |
| 3  | +81    | 11812205    | 11812205   |
| 4  | +61    | 240859600   | 240859600  |

说,给定“ 4501”,它应该返回行1,因为“ 4501”是数字“ 4081234501”的子字符串,介于“ 4081234500”和“ 4081234599”之间

给定“ 4081234500”或“ 4081234509”或“ 4081234599”,它应返回第1行。

给定“ 408”,它将返回第1行和第4行。

如何构造具有正确WHERE条件的SQL SELECT语句以返回所需的记录?

是否可以在不进行移动的情况下将FROM_NUMBER扩展到TO_NUMBER的情况下进行搜索(因为该范围内可能有1000个数字,并且处理时间太长)?

谢谢。

寻找拳头样品..您只需将字符串转换为数字

select 'OK' 
from dual
where 4501 between   
                 CAST(right('4081234500', length('4501')) AS INT)  
            AND  CAST(right('4081234599', length('4501')) AS INT)
; 

对于您的表,假设my_value包含“ 4501”

select id 
from my_table 
 where cast(my_value) between    
               cast(right(FROM_NUMBER, length(my_value)) AS INT)  
         AND  CAST(right(TO_NUMBER, length(my_value)) AS INT)

对于第二个示例,您应该使用字符串的左侧部分而不是右侧,并使用OR来使用两个条件togheter

据我了解您的问题,我进行了查询以查找确切数字是否作为子字符串出现在您的列中,或者给出的数字是否出现在您列的最后匹配数字中。 即,如果提供的数字的长度为2,则将考虑从from和to的最后两位数字进行范围搜索。

您可以尝试以下查询:

YOUR_NUMBER = 4501

SELECT * FROM TABLE
WHERE FROM_NUMBER LIKE '%' || YOUR_NUMBER || '%'
OR TO_NUMBER LIKE '%' || YOUR_NUMBER || '%'
OR YOUR_NUMBER 
BETWEEN MOD(FROM_NUMBER, POWER(10, LENGTH(YOUR_NUMBER))) 
AND MOD(TO_NUMBER, POWER(10, LENGTH(YOUR_NUMBER)));

db <> fiddle演示

干杯!!

该查询看起来很复杂,但事实并非如此。 这个想法是将数字切成若干个图案长度的块,并与图案进行比较,就像一个人一样:

with 
  s(str) as (select 81220 from dual),
  a as (
    select id, str, length(str) ls, from_number fn, to_number tn, 
           lpad(from_number, length(to_number), '0') s1, to_char(to_number) s2
      from number_range join s on length(to_number) >= length(str)),
  c(col, id, str, ls, s1, s2, sb1, sb2, match) as (
    select 1, id, str, ls, s1, s2, substr(s1, 1, ls), substr(s2, 1, ls), 
           case when str between substr(s1, 1, ls) 
                             and substr(s2, 1, ls) then 1 end
      from a
    union all
    select col + 1, id, str, ls, s1, s2, substr(s1, col + 1, ls), substr(s2, col + 1, ls),
           case when str between substr(s1, col + 1, ls) 
                             and substr(s2, col + 1, ls) then 1 end
      from c 
      where col  <= length(s1) - ls and match is null )
select id, str, sb1, sb2, prefix, from_number, to_number
  from c join number_range using (id)
  where match = 1 order by id, col;

dbfiddle演示

s要查找的值(您可以在此处使用并集输入多个值)

a -在从表中的数据from_number被lpadded用零到to_number的长度

c是递归查询。 我从两个数字中切出第一个块,然后与模式进行比较。 如果在分析之间停止( and match is null则对此负责)。 否则,它将继续。

最后,我将结果(如果找到任何内容)与原始数据结合在一起,并显示字符串的哪一部分相对应。 如果有更多行,并且您希望将它们全部删除and match is null ,则此查询查找每行的第一次出现。 希望这可以帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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