TSQL вопрос соответствия строк - PullRequest
1 голос
/ 25 января 2011

Я пытаюсь сопоставить 2 строки, используя TSQL.

Первая строка: ABCD DFHG KLJKL

Вторая строка: ABCD DFHG KLJKL - 4536764

Правило соответствия: если вторая строка начинается с первой строки, за которой следует "-" (то естьпробел, тире, пробел) и набор чисел (и ничего больше), считают это совпадением.

Есть идеи?

Ответы [ 4 ]

4 голосов
/ 25 января 2011

У меня есть два ответа для вас.

  1. Если предположить, что ваши значения FirstString не содержат символов %, _, ИЛИ [, это вернетчто ты просишьОн не только гарантирует, что вторая строка начинается с первой и сопровождается пробелом-тире-пробелом и числом, но также гарантирует, что с этой точки следуют только цифры.

    Если ваша таблица оченьв целом, тогда некластеризованный индекс, который включает FirstString и SecondString, а также любые другие столбцы, которые вы хотите выбрать SELECT (или они находятся в кластеризованном индексе), сделает этот индекс полностью покрывающим запрос и может значительно повысить производительность.

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

Обратите внимание, что если вы хотите правильно обрабатывать пробелы в конце елиstString, может потребоваться некоторая корректировка (второй запрос, использующий Len, не обрабатывает этот случай должным образом).

1 голос
/ 25 января 2011

Этот запрос удовлетворяет всем требованиям.

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
1 голос
/ 25 января 2011
select * 
from theTable 
where SecondString like FirstString + ' - %[0-9]'
and SecondString not like FirstString + ' - %[^0-9]%'

Это выберет все, что имеет вашу строку, за которой следует 1 пробел, затем тире, затем еще 1 пробел, затем любой набор цифр и ничего, кроме цифр.

EDITED: Чтобы отфильтровать результаты по любой дроби, а не только по буквам, следуя за чертой.

0 голосов
/ 25 января 2011
select * 
from theTable 
where (FirstString = SecondString) 
or (FirstString = SUBSTRING(SecondString, 0, CHARINDEX('-', SecondString))
...