【问题标题】:Returning a specific combination of alpha numeric characters返回字母数字字符的特定组合
【发布时间】:2017-03-11 01:04:26
【问题描述】:

我有一个表,其中包含 1000 行的字母数字数据,例如:

select id from status_table

id
--
N #AN54055Z / MATTHEW
345 IN  EH86963D  JP Verified o
C N # CV08705Z  PP CONF / A
UI 45 Ty
1548 47 CN #DW40205J  VERIFIED AF
N #-CT77535S
78 78Thi OK
584 C yu N #AV10045A/DONNA MO
AH28395U  VERIF BK MAH
yu YUyu789 56

我想在结果中返回一个独特的字母数字字符组合:

例如:alpha alpha numeric numeric numeric numeric numeric alpha

id
--
AN54055Z
EH86963D
CV08705Z
DW40205J
CT77535S
AV10045A
AH28395U

【问题讨论】:

    标签: sql-server regex tsql


    【解决方案1】:

    您可以使用PATINDEX 检查模式,然后将此返回值(模式开始的位置)用作SUBSTRING 中的开始位置。由于模式是静态的,SUBSTRING 的长度也是静态的

    declare @t table (x varchar(256))
    
    insert into @t values
    ('N #AN54055Z / MATTHEW'),
    ('345 IN  EH86963D  JP Verified o'),
    ('C N # CV08705Z  PP CONF / A'),
    ('UI 45 Ty'),
    ('1548 47 CN #DW40205J  VERIFIED AF'),
    ('N #-CT77535S'),
    ('78 78Thi OK'),
    ('584 C yu N #AV10045A/DONNA MO'),
    ('AH28395U  VERIF BK MAH'),
    ('yu YUyu789 56')
    
    select d.* from(
        select 
            case 
                when PATINDEX('%[a-zA-Z][a-zA-Z][0-9][0-9][0-9][0-9][0-9][a-zA-Z]%',x) > 0
                then substring(x,PATINDEX('%[a-zA-Z][a-zA-Z][0-9][0-9][0-9][0-9][0-9][a-zA-Z]%',x),8)
                else null
            end as id
        from @t) d
    where d.id is not null
    

    【讨论】:

    • 干得好。请注意,您不需要在 CASE 语句中包含 ELSE NULL; ELSE NULL 是默认行为。
    • 是的,直言不讳只是一种习惯,易于阅读@AlanBurstein
    【解决方案2】:

    您要查找的内容称为regular expressions,也称为正则表达式,它是一种用于在文本中搜索模式的宏语言。

    以下是匹配 2 个大写字母字符后跟 5 个数字和一个字母字符的正则表达式。

    [A-Z]{2}[0-9]{5}[A-Z]
    

    您可以在WHERE 语句中使用LIKE 来匹配模式,例如
    WHERE MyField LIKE '%[A-Z]{2}%'。在 SQL Server 2008 及更高版本上,您可以使用 PATINDEX 查找正则表达式的第一个匹配项的索引。

    我现在无法运行测试 SQL,但我认为这样的方法可能有效:

    SELECT
        PATINDEX ( '%([A-Z]{2}[0-9]{5}[A-Z])%', Id ) as TestPatIdx,
        CASE 
            WHEN PATINDEX ( '%([A-Z]{2}[0-9]{5}[A-Z])%', Id ) > 0 THEN
                SUBSTRING( MyField, PATINDEX ( '%([A-Z]{2}[0-9]{5}[A-Z])%' , Id ), 8 )
        END as TestResult,
        Id
    FROM
        status_table
    

    【讨论】:

    • 您不能在 T-SQL 中使用这种类型的语法:[A-Z]{2},而是需要使用 [A-Z][A-Z]。
    【解决方案3】:

    值得注意的是,如果这是您需要经常检索的数据,您可以在您的表中创建一个计算列,甚至可以根据需要对其进行索引。注意我的代码和 cmets。

    IF OBJECT_ID('tempdb..#t') is not null drop table #t;
    
    CREATE TABLE #t
    (
      -- the original column
      x varchar(256), 
      -- A computed column to extract that data ahead of time
      xx as        
      case 
        when PATINDEX('%[a-zA-Z][a-zA-Z][0-9][0-9][0-9][0-9][0-9][a-zA-Z]%',x) > 0
        then substring(x,PATINDEX('%[a-zA-Z][a-zA-Z][0-9][0-9][0-9][0-9][0-9][a-zA-Z]%',x),8)
      end persisted
    );
    
    -- optional index if you search on that column frequently
    -- NOTE That you indexes can speed up SELECT statements but will impact inserts/updates/deletes
    CREATE NONCLUSTERED INDEX nc_t_xx ON #t(xx);
    
    --declare @t table (x varchar(256))
    
    insert into #t (x) values
    ('N #AN54055Z / MATTHEW'),
    ('345 IN  EH86963D  JP Verified o'),
    ('C N # CV08705Z  PP CONF / A'),
    ('UI 45 Ty'),
    ('1548 47 CN #DW40205J  VERIFIED AF'),
    ('N #-CT77535S'),
    ('78 78Thi OK'),
    ('584 C yu N #AV10045A/DONNA MO'),
    ('AH28395U  VERIF BK MAH'),
    ('yu YUyu789 56')
    
    SELECT x, xx 
    FROM #t;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-09-15
      • 2018-08-03
      • 2011-07-09
      • 2013-10-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多