使用T-SQL检索具有许多场景的字符串的一部分
我需要一个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
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 | - |
+----+---------------------------------+---------+---+---+------+