匹配数字字符串的开头

时间:2014-07-06 10:05:40

标签: sql sql-server pattern-matching

我有一些我需要拨打电话费的电话费。

示例费用代码:

26481   Namibia - Mobile
26485   Namibia - Mobile
26482   Namibia-Mobile
441     National Call
442     National Call
674     Nauru
977     Nepal
97714   Nepal - Kathmandu
97715   Nepal - Kathmandu

示例呼叫数据:

442380010961
442380010961
441929555304
441929556253
448003163245
441305783009
447576883777
447576883777
441929554015
447434205058
447870133604
447434205058
442380436622

我如何使用SQL匹配电话号码的开头和相应的收费代码?

非常感谢任何帮助。

谢谢,

3 个答案:

答案 0 :(得分:0)

使用Case&amp ;; sql server中的通配符。请关注这些网址 * http://www.codeproject.com/Articles/39103/A-Simple-Use-of-SQL-CASE-Expression * http://www.w3schools.com/sql/sql_wildcards.asp

实施例

SELECT 
  CASE 
     WHEN tb001 like 'code%' then 'place'
     WHEN tb001 like 'code%' then 'place'
     ELSE 'No CODE'
  END
  AS COLNAME
FROM ....

答案 1 :(得分:0)

在SQL中有效地完成这项工作真的很难。您可能在TelCo工作,必须匹配(数十或数百)数百万行。

您可以应用LIKE-join加上ROW_NUMBER:

SELECT *
FROM
 ( 
   SELECT
     c.called_no
     ,p.pattern
     ,p.Destination_Tag
     ,ROW_NUMBER() OVER (PARTITION BY c.called_no ORDER BY p.pattern DESC) AS rn
   FROM
     CDRs c
   LEFT JOIN Prefixes p
     ON c.called_no LIKE p.pattern || '%'
 ) AS dt
WHERE rn = 1

或加入SUBSTR:

SELECT
  c.called_no
  ,COALESCE(p12.Destination_Tag, p11.Destination_Tag, p10.Destination_Tag,
            p9.Destination_Tag, p8.Destination_Tag, p7.Destination_Tag,
            p6.Destination_Tag, p5.Destination_Tag, p4.Destination_Tag,
            p3.Destination_Tag, p2.Destination_Tag) AS tag
FROM
  CDRs c
    LEFT JOIN Prefixes p12
      ON SUBSTR(c.called_no,1,12) = p12.pattern
    LEFT JOIN Prefixes p11
      ON SUBSTR(c.called_no,1,11) = p11.pattern
    LEFT JOIN Prefixes p10
      ON SUBSTR(c.called_no,1,10) = p10.pattern
    LEFT JOIN Prefixes p9
      ON SUBSTR(c.called_no,1,9) = p9.pattern
    LEFT JOIN Prefixes p8
      ON SUBSTR(c.called_no,1,8) = p8.pattern
    LEFT JOIN Prefixes p7
      ON SUBSTR(c.called_no,1,7) = p7.pattern
    LEFT JOIN Prefixes p6
      ON SUBSTR(c.called_no,1,6) = p6.pattern
    LEFT JOIN Prefixes p5
      ON SUBSTR(c.called_no,1,5) = p5.pattern
    LEFT JOIN Prefixes p4
      ON SUBSTR(c.called_no,1,4) = p4.pattern
    LEFT JOIN Prefixes p3
      ON SUBSTR(c.called_no,1,3) = p3.pattern
    LEFT JOIN Prefixes p2
      ON SUBSTR(c.called_no,1,2) = p2.pattern

几年前我在一个不同的DBMS上进行了模式匹配的性能测试,上面的查询有几种变体,还有使用SQL自动创建的巨大嵌套CASE(几百KB)。

表现最好的不是SQL解决方案,而是C-UDF: - )

答案 2 :(得分:0)

我假设电话号码是数字而不是字符串形式。您可以将数字转换为字符串并使用like但这样效率极低,因为您必须搜索整个表格,看起来它可能非常大。你可以使用一个技巧:

WHERE call_num BETWEEN 264810000000 AND 264819999999 OR -- matches 1st Namibia - Mobile
      call_num BETWEEN 264820000000 AND 264829999999 OR -- matches 2nd Namibia - Mobile
      call_num BETWEEN 264850000000 AND 264859999999 OR -- matches 3rd Namibia - Mobile
      etc.

这允许使用索引范围扫描,因此访问将仅限于包含感兴趣的数字的行。当然,假设call_num被编入索引。

还有旧的数据建模建议,即数据恰好是数字但永远不会用于数学运算的数据,例如id,许可证,电话号码等,应该存储为字符串。我发现这不是一个严格的规则,但在大多数情况下可能是有利的。如果电话号码已经是字符串格式并且已经编入索引,则可以使用call_num LIKE '26481%' OR call_num LIKE '26482%' OR...具有相同的扫描效率范围。