Заменить символ без использования функции ЗАМЕНИТЬ

Значения ввода базы данных SQL Server соответствуют шаблону, в котором первая позиция является символом, а затем номером. Я хочу заменить первый символ другим символом или символами. Например:

вход

    Q234567888 литий> R264747848 литий> B264712481 литий>

Выход

    I234567888 литий> I264747848 литий> U264712481 литий>

Потенциальные значения для первой позиции: [A-Z].

Я ищу вариант без использования нескольких инструкций REPLACE и не используя CASE

Если я использую CASE, мне нужно будет проверить 26 случаев или использовать REPLACE вложенным образом, я могу закончить использование инструкций 26 REPLACE. Я стараюсь избегать этого.

Пожалуйста, предложите лучший способ добиться результатов.

6 голосов | спросил sham 21 MaramWed, 21 Mar 2018 10:07:14 +03002018-03-21T10:07:14+03:0010 2018, 10:07:14

3 ответа


6

Создайте сопоставление между старым значением и новым значением в конструктор табличных значений и использовать материал , чтобы заменить символ.

declare @T table(Value varchar(10));

insert into @T values
('Q234567888'),
('R264747848'),
('B264712481');

select stuff(T.Value, 1, 1, (
                            select V.NewValue
                            from (values('Q', 'I'),
                                        ('R', 'I'),
                                        ('B', 'U')) as V(OldValue, NewValue)
                            where V.OldValue = left(T.Value, 1)
                            ))
from @T as T;
ответил Mikael Eriksson 21 MaramWed, 21 Mar 2018 10:32:49 +03002018-03-21T10:32:49+03:0010 2018, 10:32:49
2
DECLARE @values TABLE
 (  
     String CHAR(10)
 )

INSERT INTO @values
values
('Q234567888'),
('R264747848'),
('B264712481');

SELECT 
    REPLACE(String,LEFT(String,1),ca.NewValue)
FROM @values
CROSS APPLY 
(SELECT * FROM (values('Q', 'I'),
('R', 'I'),
('B', 'U'))as V(OldValue, NewValue)
WHERE v.OldValue = LEFT(string,1)                               
)ca

Вот еще один подход. Во время тестирования я использовал метод @Mikael Eriksson и CASE \ REPLACE с 26 предложениями, в тестовой таблице из 3 миллионов строк, а метод CASE - быстрее всего. Тем не менее, ни один из них не был медленным , и выше, и @ Mikael встряхнул равномерно. Конечно, YMMV.

ответил BWFC 21 MarpmWed, 21 Mar 2018 15:45:20 +03002018-03-21T15:45:20+03:0003 2018, 15:45:20
1

Я понимаю вашу озабоченность расплывчатыми запросами, особенно если они: a) медленны во время выполнения или b) недостижимы. Двадцать шесть вложенных REPLACE определенно будут претендовать на второе. Я не уверен, что CASE нужно поделиться этой судьбой.

Вы не полностью объясняете в вопросе правила сопоставления от префикса ввода к префиксу вывода. Если во входной последовательности есть последовательные прогоны, CASE может быть довольно компактным и разборчивым и, следовательно, поддерживаемым.

Оба вида

case
    when LEFT(c, 1) between 'A' and 'P' then 'U'
    when LEFT(c, 1) between 'Q' and 'R' then 'I'
    ...
end

и

case 
    when LEFT(c, 1) in ('Q', 'R') then 'I'
    when LEFT(c, 1) in ('B')      then 'U'
    ...
end

действительны, компактны, разборчивы и очевидны. По-видимому, это будет хорошо, так как в плане запроса будут жестко закодированы значения , не будет дополнительного доступа к диску или даже ссылок на буферный пул.



Конечно, оптимизатор запросов может свободно обращаться с ними любым способом. Если он встроен в достаточно лабиринтный запрос, это может не выполняться. Только вы знаете полную сложность фактического запроса.

ответил Michael Green 22 MarpmThu, 22 Mar 2018 14:30:32 +03002018-03-22T14:30:32+03:0002 2018, 14:30:32

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132