A SARGABLE решение состоит в том, чтобы написать функцию, которая принимает целевое значение ('12345678'
) и вставляет разделители ('.'
) в каждый третий символ справа налево.Затем результат ('12.345.678'
) можно использовать в предложении where
и использовать индекс для CAMPO
.
. Следующий код демонстрирует подход без создания пользовательской функции (UDF).Вместо этого используется рекурсивное общее табличное выражение (CTE) для обработки входной строки по три символа за раз, чтобы построить пунктирную целевую строку.Результат используется в запросе к образцу таблицы.
Чтобы увидеть результаты из рекурсивного CTE, замените окончательный оператор select
комментарием select
непосредственно над ним.
-- Sample data.
declare @Samples as Table ( SampleId Int Identity, DottedDigits VarChar(20) );
insert into @Samples ( DottedDigits ) values
( '1' ), ( '12' ), ( '123' ), ( '1.234' ), ( '12.345' ),
( '123.456' ), ( '1.234.567' ), ( '12.345.678' ), ( '123.456.789' );
select * from @Samples;
-- Query the data.
declare @Target as VarChar(15) = '12345678';
with
Target as (
-- Get the first group of up to three characters from the tail of the string ...
select
Cast( Right( @Target, 3 ) as VarChar(20) ) as TargetString,
Cast( Left( @Target, case when Len( @Target ) > 3 then Len( @Target ) - 3 else 0 end ) as VarChar(20) ) as Remainder
union all
-- ... and concatenate the next group with a dot in between.
select
Cast( Right( Remainder, 3 ) + '.' + TargetString as VarChar(20) ),
Cast( Left( Remainder, case when Len( Remainder ) > 3 then Len( Remainder ) - 3 else 0 end ) as VarChar(20) )
from Target
where Remainder != ''
)
-- To see the intermediate results replace the final select with the line commented out below:
--select TargetString from Target;
select SampleId, DottedDigits
from @Samples
where DottedDigits = ( select TargetString from Target where Remainder = '' );
Альтернативным подходом было бы добавить индексированный вычисляемый столбец к таблице, содержащей Replace( CAMPO, '.', '' )
.