使用T-SQL检索具有许多场景的字符串的一部分

使用T-SQL检索具有许多场景的字符串的一部分,sql,sql-server,tsql,Sql,Sql Server,Tsql,我需要一个T-SQL查询来获得下面指定的输出,该输出将覆盖所有情况。我试过这样做,但没有成功: select code, substring(code, patindex('%[0-9]%', code), case when patindex('%[. ,/-]%', substring(code, patindex('%[0-9]%', code), len(code))) <&g

我需要一个T-SQL查询来获得下面指定的输出,该输出将覆盖所有情况。我试过这样做,但没有成功:

select 
    code,
    substring(code, patindex('%[0-9]%', code),
                    case 
                       when patindex('%[. ,/-]%', substring(code, patindex('%[0-9]%', code), len(code))) <> 0
                          then patindex('%[. ,/-]%', substring(code, patindex('%[0-9]%', code), len(code))) - 1 
                          else patindex('%[. ,/-]%', substring(code, patindex('%[0-9]%', code), len(code)))
                     end) 
from 
    table
规则

从第一次出现的数字开始 在特殊字符后切分字符串,/-有效大小写 2.1如果字符串在3个数字之后有效,例如:AB B0-23456.123-0-23456 2.2如果字符串在有效空格后有3个以上的数字,例如:AB 1234 5678 9545 3214.123-1234 5678 9545 3214
我相信这将满足您的所有标准,但一定要对照此处未提供的边缘情况进行检查,以确保它符合您的期望

DECLARE @table as TABLE (code VARCHAR(40))

INSERT INTO @table
(code)
Values
('AB 123456.123'),
('AB 123456/123'),
('AB 123456-123'),
('AB B0-23456.123'),
('AB 1234 5678 954 3214.123'),
('AB 1234 5678 9545/3214.123'),
('AB 123456 123'),
('AB.123456 123'),
('AB..123456 123'),
('AB..1C23456 123')


SELECT 
code as [input],
SUBSTRING(code,PATINDEX('%[0-9]%', code),
CASE WHEN PATINDEX('%[ -][0-9][0-9][0-9][0-9]%',SUBSTRING(code,PATINDEX('%[0-9]%', code),LEN(code))) <> 0
THEN 
    CASE WHEN PATINDEX('%[.,/]%',SUBSTRING(code,PATINDEX('%[0-9]%', code),LEN(code))) < ISNULL(NULLIF(PATINDEX('%[ -][0-9][0-9][0-9][^0-9]%',SUBSTRING(code,PATINDEX('%[0-9]%', code),LEN(code))),0),LEN(code))
    THEN PATINDEX('%[.,/]%',SUBSTRING(code,PATINDEX('%[0-9]%', code),LEN(code)))-1
    ELSE ISNULL(NULLIF(PATINDEX('%[ -][0-9][0-9][0-9][^0-9]%',SUBSTRING(code,PATINDEX('%[0-9]%', code),LEN(code))),0),LEN(code))
    END
ELSE PATINDEX('%[. ,/-]%', SUBSTRING(code,PATINDEX('%[0-9]%', code),LEN(code)))-1
END
) as [output]
FROM @table

编辑:修改内部案例语句,以更正注释中提到的边缘案例,只是为了证明这可以在不使用CTE的情况下完成:

老实说:这是一场噩梦。对于这一点,T-SQL绝对是错误的工具

因为你的问题答案不充分,我放了一个不充分的答案,我被催促以某种方式解决这个问题。这是一个体育精神的问题

DECLARE @mockup TABLE(ID INT IDENTITY, YourString VARCHAR(1000));
INSERT INTO @mockup VALUES
 ('AB 123456.123')                 
,('AB 123456/123')                 
,('AB 123456-123')                 
,('AB B0-23456.123')               
,('AB 1234 5678 9545 3214.123')    
,('AB 123456 123')                 
,('AB.123456 123')                 
,('AB..123456 123')                
,('AB..1C23456 123')
,('AB 1234 5678 954 3214-12345.123');
-噩梦

以CutForRules为例 选择t.ID ,t.YourString ,按t.ID顺序按选择空碎片索引超额分配行号 ,c AsXml ,d.value'text[1],'varchar100'片段 ,ISNUMERICd.value'text[1],'varchar100'FragmentIsNum ,LENd.value'text[1],'varchar100'FragmentLength ,d.值'@dlmt','varchar10'分隔符 来自@mockup t 交叉应用程序选择反向substringt.YourString,PATINDEX“%[0-9]”,t.YourString,1000 Aa 交叉应用程序选择反转substringa,PATINDEX“%[/.-]%”,a+11000 Bb 交叉应用程序选择CAST+replaceb、“/”、“|”、“、”、“、”、“-”、“|”、+作为XML Cc 交叉应用c.nodes'/x'Dd 选择t1.ID ,t1.YourString , 选择CONCATt2.Delimiter,t2.Fragment 来自CutForRules t2 其中t1.ID=t2.ID 和t2.FragmentIndext2.FragmentIndex 和t3。分隔符=“”
而t3.fragmentLength似乎是模式的一个问题。从一开始就应该有两个独立的列。这里有什么规则?这太模糊了,我看不出有什么确切的规则。像A./XY39GH093-7734FD 8374这样的东西怎么样ABCD@SeanLange39GH093-7734是规则1的答案。从数字2的第一次出现开始。在特殊字符后切分字符串,/-有效大小写-如果字符串有-在3个数字后有效,例如:AB B0-23456.123-0-23456-如果字符串在空格后有3个以上的数字有效,例如:AB 1234 5678 9545 3214.123-1234 5678 9545 3214这是一场噩梦!!!您应该使用编程语言并修复数据。在t-sql中这样做不是一个好方法,Python可以胜任这项任务。读取正则表达式-'re'是的,它对上述示例数据有效,但2.2规则已被破坏,例如:AB 1234 5678 954 3214-12345.123---预期:1234 5678查询输出为1234 5678 954。其余都可以。谢谢你的邀请effort@Vman上面的代码已更新,以处理您提供的失败用例示例。是的,它对上述示例数据有效,但2.2规则已被破坏,例如:AB 1234 5678 954 3214-12345.123---预期:1234 5678查询输出为1234 5678 954。其余都可以。谢谢你的努力,我理解了这个想法。但是我需要查询来满足条件。谢谢最后噩梦处理了我所有的场景。但我需要实施的想法。你能更新一下想法吗?非常感谢再次感谢Hanks@shnugosorry我错过了。接受了答案并投了赞成票
DECLARE @mockup TABLE(ID INT IDENTITY, YourString VARCHAR(1000));
INSERT INTO @mockup VALUES
 ('AB 123456.123')                 
,('AB 123456/123')                 
,('AB 123456-123')                 
,('AB B0-23456.123')               
,('AB 1234 5678 9545 3214.123')    
,('AB 123456 123')                 
,('AB.123456 123')                 
,('AB..123456 123')                
,('AB..1C23456 123')
,('AB 1234 5678 954 3214-12345.123');
+----+---------------------------------+---------+---+---+------+
|    | YourString                      |Fragment | N | L | Delm |
+----+---------------------------------+---------+---+---+------+
| 1  | AB 123456.123                   | 123456  | 1 | 6 | NULL |
+----+---------------------------------+---------+---+---+------+
| 2  | AB 123456/123                   | 123456  | 1 | 6 | NULL |
+----+---------------------------------+---------+---+---+------+
| 3  | AB 123456-123                   | 123456  | 1 | 6 | NULL |
+----+---------------------------------+---------+---+---+------+
| 4  | AB B0-23456.123                 | 0       | 1 | 1 | NULL |
+----+---------------------------------+---------+---+---+------+
| 4  | AB B0-23456.123                 | 23456   | 1 | 5 | -    |
+----+---------------------------------+---------+---+---+------+
| 5  | AB 1234 5678 9545 3214.123      | 1234    | 1 | 4 | NULL |
+----+---------------------------------+---------+---+---+------+
| 5  | AB 1234 5678 9545 3214.123      | 5678    | 1 | 4 |      |
+----+---------------------------------+---------+---+---+------+
| 5  | AB 1234 5678 9545 3214.123      | 9545    | 1 | 4 |      |
+----+---------------------------------+---------+---+---+------+
| 5  | AB 1234 5678 9545 3214.123      | 3214    | 1 | 4 |      |
+----+---------------------------------+---------+---+---+------+
| 6  | AB 123456 123                   | 123456  | 1 | 6 | NULL |
+----+---------------------------------+---------+---+---+------+
| 7  | AB.123456 123                   | 123456  | 1 | 6 | NULL |
+----+---------------------------------+---------+---+---+------+
| 8  | AB..123456 123                  | 123456  | 1 | 6 | NULL |
+----+---------------------------------+---------+---+---+------+
| 9  | AB..1C23456 123                 | 1C23456 | 0 | 7 | NULL |
+----+---------------------------------+---------+---+---+------+
| 10 | AB 1234 5678 954 3214-12345.123 | 1234    | 1 | 4 | NULL |
+----+---------------------------------+---------+---+---+------+
| 10 | AB 1234 5678 954 3214-12345.123 | 5678    | 1 | 4 |      |
+----+---------------------------------+---------+---+---+------+
| 10 | AB 1234 5678 954 3214-12345.123 | 954     | 1 | 3 |      |
+----+---------------------------------+---------+---+---+------+
| 10 | AB 1234 5678 954 3214-12345.123 | 3214    | 1 | 4 |      |
+----+---------------------------------+---------+---+---+------+
| 10 | AB 1234 5678 954 3214-12345.123 | 12345   | 1 | 5 | -    |
+----+---------------------------------+---------+---+---+------+