我有一个varchar类型列,其文本类似于20171126-401-9-4496
。
该字符串有4个部分,每个部分都有固定的长度:
第1节--8位数
第2节--4位数
第3节 - 2位数
第4节--4位
我想用' 0'填充字符串的第2和第3部分,以便文本变为
20171126-0401-09-4496
满足每个部分的固定长度要求。我尝试使用SUBSTRING
和CHARINDEX
函数,但无法获得所需的结果。如何解决这个问题?
答案 0 :(得分:6)
PARSENAME
黑客的完美时间!
SELECT PARSENAME(REPLACE(MyColumn,'-','.'),4)+'-'+
RIGHT('0000'+PARSENAME(REPLACE(MyColumn,'-','.'),3),4)+'-'+
RIGHT('00'+PARSENAME(REPLACE(MyColumn,'-','.'),2),2)+'-'+
PARSENAME(REPLACE(MyColumn,'-','.'),1)
答案 1 :(得分:1)
如果您总是希望在这些位置上插入'0',那么它将起作用:
select stuff (stuff('20171126-401-9-4496',14,0,0),10,0,'0')
如果我们有一个可变长度的字段,那么它将像这样工作(第一个字段的例子):
select @str = '20175555-0001-9-46'
select @len = (select charindex('-',substring(@str,10,100)))
select
case
when @len = 2
then stuff(@str,10,0,'000')
when @len = 3
then stuff(@str,10,0,'00')
when @len = 4
then stuff(@str,10,0,'0')
else
@str
end as string
答案 2 :(得分:1)
接受Tab Allemen所做的事情,您也可以将它应用于第一列和最后一列......
declare @var varchar(18) = '201711-1-9-4496'
SELECT right('00000000' + parsename(replace(@var,'-','.'),4),8) + '-'
+ right('0000' + parsename(replace(@var,'-','.'),3),4) + '-'
+ right('00' + parsename(replace(@var,'-','.'),2),2) + '-'
+ right('0000' + parsename(replace(@var,'-','.'),1),4)
答案 3 :(得分:0)
如果你真的喜欢派生表...
DECLARE @mytable TABLE (mynewstring varchar(100)) --replace @mytable with your table name
INSERT INTO @mytable VALUES
('20171126-401-9-4496')
,('1-401-9-4496')
,('1-1-1-1')
,('---')
SELECT dT4.FirstVal + SecondVal + ThirdVal + FourthVal [newval]
FROM (
SELECT LEFT('00000000', len('00000000') - (dT3.[firstD] - 1)) + LEFT(mynewstring, [firstD]) [FirstVal]
,LEFT('0000', len('0000') - ([secondD] - [firstD] - 1)) + SUBSTRING(mynewstring, [firstD] + 1, [secondD] - [firstD]) [SecondVal]
,LEFT('00', len('00') - ([thirdD] - [secondD] - 1)) + SUBSTRING(mynewstring, [secondD] + 1, [thirdD] - [secondD]) [ThirdVal]
,LEFT('0000', len('0000') - (len(mynewstring) - [thirdD])) + SUBSTRING(mynewstring, [thirdD] + 1, len(mynewstring) - [thirdD]) [FourthVal]
FROM (
SELECT dT2.*
,CHARINDEX('-', dT2.mynewstring, dT2.[secondD] + 1) [thirdD]
FROM (
SELECT dT.*
,CHARINDEX('-', dT.mynewstring, dT.[firstD]+1) [secondD]
FROM (
SELECT mynewstring
,CHARINDEX('-', mynewstring, 0) [firstD]
FROM @mytable
) AS dT
) AS dT2
) AS dT3
) AS dT4
会产生输出:
newval
20171126-0401-09-4496
00000001-0401-09-4496
00000001-0001-01-0001
00000000-0000-00-0000
该算法依次抓取破折号的位置。然后它为该位置进行0和字符串连接。最后,这些值被连接起来。
答案 4 :(得分:0)
要圆滑并显示一个拆分字符串方法,以防有人看到这个问题,并且当parsename hack无法工作时有5个或更多部分。
DECLARE @Table AS TABLE (col1 VARCHAR(50))
INSERT INTO @Table VALUES
('20171127-4301-9-4496'),('20171125-301-9-4496'),('20171124-21-9-4496'),('20171123-1-9-4496'),('20171122-1-09-4496')
SELECT
*
,NewFormat = p1 + '-' + RIGHT('0000' + P2, 4) + '-' + RIGHT('00' + P3,2) + '-' + P4
FROM
(
SELECT col1, xmlcol1 = CAST(('<row><col>' + REPLACE(col1,'-','</col><col>') + '</col></row>') AS XML)
FROM
@Table
) t
CROSS APPLY
(SELECT
t.n.value('col[1]','VARCHAR(50)') as P1
,t.n.value('col[2]','VARCHAR(50)') as P2
,t.n.value('col[3]','VARCHAR(50)') as P3
,t.n.value('col[4]','VARCHAR(50)') as P4
FROM
t.xmlcol1.nodes ('/row') AS t(n)) c
你也可以进行扩展,这样你就可以测试字符串的部分是否有超过4个字符等,而不是填充它或者什么都没有。