TSQL字符串匹配问题

发布于 2024-10-13 18:52:21 字数 237 浏览 3 评论 0原文

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

第一个字符串:      ABCD DFHG KLJKL

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

匹配规则:如果第二个字符串以第一个字符串开头,后跟“ - ”(即空格、破折号) ,空格)和一组数字(没有其他),将其视为匹配。

有什么想法吗?

I am trying to match 2 strings using TSQL.

First string:      ABCD DFHG KLJKL

Second string: ABCD DFHG KLJKL - 4536764

Matching rule: if second string begins with the first string followed by " - " (that is, space, dash, space) and a set of numbers (and nothing else), consider it a match.

Any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

青瓷清茶倾城歌 2024-10-20 18:52:21

我有两个答案给你。

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

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

    <前><代码>选择 *
    从字符串
    在哪里
    SecondString LIKE FirstString + ' - [0-9]%'
    并且 SecondString 与 FirstString + ' - %[^0-9]%' 不同;

    我还认为,如果 FirstString 为空并且 SecondString 立即以“-”开头,那么根据规范它是正确的。

  2. 如果您的 FirstString 值确实包含上述​​任何字符,那么这里有一种处理方法:

    <前><代码>选择*
    从字符串
    在哪里
    左 (第二个字符串, Len(第一个字符串) + 3) = 第一个字符串 + ' - '
    AND Len(SecondString) > Len(第一个字符串) + 3
    AND Substring(SecondString, Len(FirstString) + 4, 2147483647) 不喜欢 '%[^0-9]%';

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

    WITH S AS (
       选择
          *,
          替换(替换(替换(替换(
             第一个字符串,
             '\'、'\\'),
             '%', '\%'),
             '_', '\_'),
             '[', '\[' --' 只是修复不稳定代码着色的注释
          ) 第一个字符串转义
       从字符串
    )
    选择 *
    从S
    在哪里
       SecondString LIKE FirstStringEscaped + ' - [0-9]%' ESCAPE '\' --'
       AND SecondString 不喜欢 FirstStringEscaped + ' - %[^0-9]%' ESCAPE '\'; --'
    

请注意,如果您想正确处理 FirstString 末尾的空格,可能需要进行一些调整(使用 Len 的第二个查询无法正确处理这种情况)。

I have two answers for you.

  1. Assuming that your FirstString values do not contain any of the characters %, _, OR [, this will return what you're asking for. Not only does it guarantee that the second string begins with the first and is followed by space-dash-space and a number, it also makes sure that only numbers follow from that point onward.

    If your table is very wide at all, then a nonclustered index that includes FirstString and SecondString as well as whatever other columns you want SELECTed (or they're in the clustered index) will make that index fully cover the query and could greatly improve performance.

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

    I would also submit that if the FirstString is blank and SecondString starts immediately with ' - ' then it is correct per the specs.

  2. If your FirstString value DOES contain any of the above characters, then here's one way to handle that:

    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]%';
    

    This is kind of strange territory, here, so I would experiment also with this version to see if it performs any better:

    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 '\'; --'
    

Please note that if you want to properly handle spaces at the end of FirstString, some adjustment may be required (the second query which uses Len does not handle this case properly).

花心好男孩 2024-10-20 18:52:21
select * 
from theTable 
where SecondString like FirstString + ' - %[0-9]'
and SecondString not like FirstString + ' - %[^0-9]%'

这将选择包含您的字符串的任何内容,后跟 1 个空格,后跟破折号,再后跟 1 个空格,后跟任意一组数字,除了数字之外什么都没有。

编辑:要过滤掉破折号后面的任何杂乱的结果,而不仅仅是字母。

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

This will select anything that has your string, followed by 1 space, followed by a dash, followed by 1 more space, followed by any set of numbers, and nothing but numbers.

EDITED: To filter out results with any cruft, not just letters, following the dash.

淡淡绿茶香 2024-10-20 18:52:21

该查询满足所有要求。

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

This query satisfies all the requirements.

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

Here's a test table, showing you all the test cases

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
孤城病女 2024-10-20 18:52:21
select * 
from theTable 
where (FirstString = SecondString) 
or (FirstString = SUBSTRING(SecondString, 0, CHARINDEX('-', SecondString))
select * 
from theTable 
where (FirstString = SecondString) 
or (FirstString = SUBSTRING(SecondString, 0, CHARINDEX('-', SecondString))
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文