
[英]How to split string to characters and then enclose every character with a tag
[英]How to insert a character into a string every 3 characters from the right
我有一个由数字组成的字符串。 字符串的长度范围从 1 个字符到 9 个字符。 我想从右边每三个字符插入一个破折号 (-)。 这仅与具有三个以上字符的字符串相关。 这只是一个 select 语句,因为我不想实际更新字符串本身。
例如,
8 should return 8
476 should return 476
4767 should return 4-767
45907392 should return 45-907-392
845907392 should return 845-907-392
这应该有效:
select
*,
replace(format(n,'#,#'),',','-')
from (values (8),(476),(4767),(45907392),(845907392)) x (n)
改成。 如果它在您的系统中是千位分隔符,或者在 FORMAT function 中提供文化作为第三个参数,所以它总是一样的。
由于 SQL Server 2012 您可以使用FORMAT
function ,如其他答案中所述。 如果您也想格式化像“abcde”这样的字符串值,您只能使用这样的字符串函数:
DECLARE @str VARCHAR(100) = '845907392';
-- 845-907-392
SELECT REVERSE(SUBSTRING(REVERSE(@str), 7, 3))
+ CASE WHEN LEN(@str)>6 THEN '-' ELSE '' END
+ REVERSE(SUBSTRING(REVERSE(@str), 4, 3))
+ CASE WHEN LEN(@str)>3 THEN '-' ELSE '' END
+ REVERSE(SUBSTRING(REVERSE(@str), 1, 3))
您还可以创建 function:
CREATE FUNCTION dbo.GetFormatTripleDash (@str varchar(255))
RETURNS VARCHAR(255)
AS
BEGIN
DECLARE @retStr VARCHAR(255) = REVERSE(SUBSTRING(REVERSE(@str), 7, 3))
+ CASE WHEN LEN(@str)>6 THEN '-' ELSE '' END
+ REVERSE(SUBSTRING(REVERSE(@str), 4, 3))
+ CASE WHEN LEN(@str)>3 THEN '-' ELSE '' END
+ REVERSE(SUBSTRING(REVERSE(@str), 1, 3))
RETURN(@retStr)
END
你可以像这样使用这个函数:
-- 845-907-392
SELECT dbo.GetFormatTripleDash('845907392')
使用 function 的更灵活的解决方案。 现在您可以使用更长的字符串值,并且可以定义由-
字符分隔的零件大小。
CREATE FUNCTION dbo.GetFormatDash (@str varchar(255), @partSize INT = 3)
RETURNS VARCHAR(255)
AS
BEGIN
DECLARE @startSize INT = 0;
DECLARE @retStr VARCHAR(255) = '';
WHILE @startSize < LEN(@str)
BEGIN
SET @retStr = REVERSE(SUBSTRING(REVERSE(@str), @startSize + 1, @partSize)) + CASE WHEN @startSize > 0 THEN '-' ELSE '' END + @retStr;
SET @startSize = @startSize + @partSize;
END
RETURN(@retStr)
END
您可以像这样使用这个改进的 function:
-- 12-345-678-901-234-567-890
SELECT dbo.GetFormatDash('12345678901234567890', DEFAULT)
SELECT dbo.GetFormatDash('12345678901234567890', 3)
-- 12345-67890-12345-67890
SELECT dbo.GetFormatDash('12345678901234567890', 5)
使用format()
function 试试这个。
Select Replace(format(8, '#,##0'), ',', '-')
Select Replace(format(476, '#,##0'), ',', '-')
Select Replace(format(45907392, '#,##0'), ',', '-')
Select Replace(format(845907392, '#,##0'), ',', '-')
现场db<>fiddle演示。
它有点恶心,但它的工作原理! 试试看,如果你同意,请告诉我
SELECT
CASE
WHEN LEN(yourColumn)>6 THEN format(CAST(YourColumn AS NUMERIC), '###-###-###')
WHEN LEN(YourColumn)>3 THEN format(CAST(YourColumn AS NUMERIC), '###-###')
ELSE YourColumn
END
这是另一种方法,尽管输入更多
SELECT
CASE
WHEN LEN(yourColumn)>6 THEN SUBSTRING(YourColumn, 1, 3) +'-'+ SUBSTRING(YourColumn, 4, 3)
WHEN LEN(YourColumn)>3 THEN REVERSE(SUBSTRING(REVERSE(YourColumn), 1, 3) +'-'+ SUBSTRING(REVERSE(YourColumn), 4, 3))
ELSE YourColumn
END
尝试这个。 我相信它也可以通过一些努力进行扩展以允许任意数量的字符
declare @input nvarchar(100) = '845907392'
declare @separator char(1) = '-'
--option1 - CTE
;with dash1 as (
select isnull(stuff(reverse(@input), 1+3, 0, @separator), reverse(@input)) as v
)
, dash2 as(
select isnull(stuff(v, 1+7, 0, @separator), v) as v from dash1
)
select reverse(v) from dash2
--option2 - Non CTE
select reverse(isnull(stuff(isnull(stuff(reverse(@input), 1+3, 0, @separator), reverse(@input)), 1+7, 0, @separator), isnull(stuff(reverse(@input), 1+3, 0, @separator), reverse(@input))))
具有递归 CTE 的解决方案:
with cte as (
select col, len(col) - 3 pos from tablename
union all
select
cast(left(col, pos) + '-' + right(col, len(col) - pos) as varchar(100)),
pos - 3
from cte
where pos > 0
)
select col from cte
where pos <= 0
见演示。
结果:
> | col |
> | :---------- |
> | 8 |
> | 476 |
> | 845-907-392 |
> | 45-907-392 |
> | 4-767 |
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.