简体   繁体   中英

Add comma after every 3rd character

I have a table with a varchar column for CCodes - it's a string of 60-character where every 3 digits is a CCode.

Example:

149001006000000000000000000000000000000000000000000000000000

This translates to following CCodes: 149, 001, 006, 000, ..
I would like to query this to find certain CCode(s) (example 347).

I can't use "like" keyword because they may be shifted (example 003470111 - this does not qualify because that translates to 003, 470 and 111 and none is 347)

Additionally I'd need it to work in a select statement and preferably not using a user-defined function (due to performance; it's a large table).

My current solution (my colleague's actually) uses stuff() to add comma after every 3rd character then string split them (comma as delimiter).
With this we use the cross apply to get the split CCode.

Example:

select ccode = splitcodes.value
from ...
cross apply string_split(stuff(stuff(... (CCodes, 4, 0, ','), ...), ',') as splitcodes

I'm wondering: Is there a better way?
Thank you.

It seems that you need to split the stored 60-character string at every 3rd character to find a substring ( CCode ) with specific value and this is different from the question's title ( "Add comma after every 3rd character" ). So, if this is the case and if the string has a maximum length of 60 characters, you may use a tally table with 20 (60/3) rows in the following way:

SELECT d.CCodes
FROM (VALUES
   ('149001006000000000000000000000000000000000000000000000000000')
) d (CCodes)
CROSS APPLY (VALUES
   (0), (1), (2), (3), (4), (5), (6), (7), (8), (9), 
   (10), (11), (12), (13), (14), (15), (16), (17), (18), (19)
) a (N)
WHERE SUBSTRING(d.CCodes, a.N * 3 + 1, 3) = '001'

Of course, if you want to select the rows if a specific substring ( CCode ) exists, you can use the following statement:

SELECT d.CCodes
FROM (VALUES
   ('149001006000000000000000000000000000000000000000000000000000')
) d (CCodes)
WHERE EXISTS (
   SELECT 1
   FROM (VALUES
      (0), (1), (2), (3), (4), (5), (6), (7), (8), (9), 
      (10), (11), (12), (13), (14), (15), (16), (17), (18), (19)
   ) a (N)
   WHERE SUBSTRING(d.CCodes, a.N * 3 + 1, 3) = '149'
)

Add comma after every 3rd character

One approach is a recursive CTE:

with cte as (
      select convert(varchar(max), '') as str, convert(varchar(max), ccode) as rest, ccode
      from (values ('149001006000000000000000000000000000000000000000000000000000')) v(ccode)
      union all
      select concat(str, ',', left(rest, 3)), stuff(rest, 1, 3, ''), ccode
      from cte
      where rest <> ''
     )
select stuff(max(str), 1, 1, '')
from cte
group by ccode

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM