Я думаю, что, возможно, здесь лучше использовать внешнюю функцию, но если это слишком много, вы можете получить хитрость с помощью strtok_split_to_table
, xml_agg
и regexp_replace
, чтобы разорвать строку на части, заменить символы, используя вашикритерии и объедините их вместе:
WITH cte AS (SELECT REGEXP_REPLACE('this is a test of this functionality', '(.)', '\1,') AS fullname FROM Sys_Calendar.calendar WHERE calendar_date = CURRENT_DATE)
SELECT
REGEXP_REPLACE(REGEXP_REPLACE((XMLAGG(tokenout ORDER BY tokennum) (VARCHAR(200))), '(.) (.)', '\1\2') , '(.) (.)', '\1\2')
FROM
(
SELECT
tokennum,
outkey,
CASE WHEN tokennum = 1 OR tokennum mod 4 = 0 OR token = ' ' THEN token ELSE 'X' END AS tokenout
FROM TABLE (strtok_split_to_table(cte.fullname, cte.fullname, ',')
RETURNS (outkey VARCHAR(200), tokennum integer, token VARCHAR(200) CHARACTER SET UNICODE)) AS d
) stringshred
GROUP BY outkey
Это не будет быстрым для большого набора данных, но может быть достаточно в зависимости от того, сколько данных вам нужно обработать.
Разбивкаэто вниз:
WITH cte AS (SELECT REGEXP_REPLACE('this is a test of this functionality', '(.)', '\1,') AS fullname FROM Sys_Calendar.calendar WHERE calendar_date = CURRENT_DATE)
Этот CTE просто добавляет запятую между каждым символом нашей входящей строки, используя эту функцию regexp_replace
.Ваше имя будет выглядеть как J,o,h,n, ,D,o,e
.Вы можете проигнорировать часть sys_calendar, я просто вставил ее, чтобы она выдавала ровно 1 запись для тестирования.
SELECT
tokennum,
outkey,
CASE WHEN tokennum = 1 OR tokennum mod 4 = 0 OR token = ' ' THEN token ELSE 'X' END AS tokenout
FROM TABLE (strtok_split_to_table(cte.fullname, cte.fullname, ',')
RETURNS (outkey VARCHAR(200), tokennum integer, token VARCHAR(200) CHARACTER SET UNICODE)) AS d
Этот подзапрос является важным битом.Здесь мы создаем запись для каждого персонажа в вашем имени.strtok_split_to_table
выполняет здесь работу, разделяя входящее имя запятой (которое мы добавили в CTE)
Оператор Case
просто запускает критерии, заменяя 'X' на правильные позиции (запись 1,или кратное 4, а не пробел).
SELECT
REGEXP_REPLACE(REGEXP_REPLACE((XMLAGG(tokenout ORDER BY tokennum) (VARCHAR(200))), '(.) (.)', '\1\2') , '(.) (.)', '\1\2')
Наконец, мы используем XMLAGG
, чтобы объединить множество записей обратно в одну строку в одной записи.Поскольку XMLAGG
добавляет пробел между каждым символом, мы должны ударить его пару раз с помощью regexp_replace
, чтобы перевернуть эти пробелы в ноль.
Итак ... это некрасиво, но делает свою работу.
Вышеприведенный код выплевывает:
tXXs XX X XeXX oX XhXX fXXXtXXXaXXXy