TSQL字符串匹配问题

时间:2011-01-25 17:57:01

标签: sql string tsql sql-server-2008 pattern-matching

我正在尝试使用TSQL匹配2个字符串。

第一个字符串:ABCD DFHG KLJKL

第二个字符串:ABCD DFHG KLJKL - 4536764

匹配规则:如果第二个字符串以第一个字符串开头,后跟“ - ”(即空格,短划线,空格)和一组数字(没有其他内容),请将其视为匹配。

有什么想法吗?

4 个答案:

答案 0 :(得分:4)

我有两个答案。

  1. 假设您的FirstString值不包含任何字符%_或OR [,这将返回您要求的内容。它不仅保证第二个字符串以第一个字符串开头,后面跟着空格 - 空格和数字,它还确保从那一点开始只跟随数字。

    如果你的表非常宽,那么包含FirstString和SecondString的非聚集索引以及你想要SELECTed的任何其他列(或者它们在聚簇索引中)将使该索引完全覆盖查询并且可以大大提高了性能。

    SELECT * 
       FROM Strings
       WHERE
          SecondString LIKE FirstString + ' - [0-9]%'
          AND SecondString NOT LIKE FirstString + ' - %[^0-9]%';
    

    我还会提交,如果FirstString为空,SecondString立即以' - '开头,那么根据规格它是正确的。

  2. 如果你的FirstString值包含任何上述字符,那么这是处理它的一种方法:

    SELECT * 
       FROM Strings
       WHERE
          Left(SecondString, Len(FirstString) + 3) = FirstString + ' - '
          AND Len(SecondString) > Len(FirstString) + 3
          AND Substring(SecondString, Len(FirstString) + 4, 2147483647) NOT LIKE '%[^0-9]%';
    

    这是一个奇怪的领域,所以我也会尝试使用这个版本,看它是否表现更好:

    WITH S AS (
       SELECT
          *,
          Replace(Replace(Replace(Replace(
             FirstString,
             '\', '\\'),
             '%', '\%'),
             '_', '\_'),
             '[', '\[' --' just a comment to fix wonky code colorization
          ) FirstStringEscaped
       FROM Strings
    )
    SELECT *
    FROM S
    WHERE
       SecondString LIKE FirstStringEscaped + ' - [0-9]%' ESCAPE '\' --'
       AND SecondString NOT LIKE FirstStringEscaped + ' - %[^0-9]%' ESCAPE '\'; --'
    
  3. 请注意,如果要在FirstString末尾正确处理空格,可能需要进行一些调整(使用Len的第二个查询无法正确处理此情况)。

答案 1 :(得分:1)

此查询满足所有要求。

select *
from #strings
where
  -- s2 contains s1 as the prefix.
  -- The addition of '.' is because sql considers ('abc' = 'abc ')
  LEFT(s2,Len(s1))+'.' = s1+'.'

  -- next 4 chars are space-dash-space-digit
  AND SUBSTRING(s2, Len(s1)+1, Len(s2)) LIKE ' - %[0-9]%'

  -- no non-digit letters after that
  AND NOT STUFF(s2, 1, len(s1)+4, '') LIKE '%[^0-9]%' 

  AND s1 > '' -- reject empty string1, added just in case

这是一个测试表,显示所有测试用例

create table #strings (s1 varchar(100), s2 varchar(100))
insert into #strings values
    ('ABCD DFHG KLJKL', 'ABCD DFHG KLJKL - abc'), -- no, not number
    ('ABCD DFHG KLJKL', 'ABCD DFHG KLJKL - 123'), -- yes
    ('ABCD ', 'ABCD - 123'), -- no, 2nd string is first + '-' without space
    ('ABCD DFHG KLJKL - 123', 'ABCD DFHG KLJKL'), -- no, reversed
    ('KLJKL', 'KLJKL - 1.234'), -- ?? no, 2nd string is not digits only
    ('KL%', 'KLJKL - 1.234'), -- ?? no, 2nd string is not digits only
    ('', ' - 5234'), -- ?? no, blank string is not a match
    (null, ' - 1234'), -- ?? no, null is not equal to blank, which is not a match anyway
    ('ABCD DFHG KLJKL', null) -- no, of course not

答案 2 :(得分:1)

select * 
from theTable 
where SecondString like FirstString + ' - %[0-9]'
and SecondString not like FirstString + ' - %[^0-9]%'

这将选择包含字符串的任何内容,后跟1个空格,后跟短划线,后跟1个空格,后跟任意数字组,只有数字。

已编辑:要使用任何残骸过滤掉结果,而不仅仅是字母,请使用短划线。

答案 3 :(得分:0)

select * 
from theTable 
where (FirstString = SecondString) 
or (FirstString = SUBSTRING(SecondString, 0, CHARINDEX('-', SecondString))