简体   繁体   English

sql格式化和填充列

[英]sql formatting and padding of a column

I"m trying to format and pad LSD numbers to look like this. 100/14-34-018-09W4/00 我正在尝试格式化和填充LSD数字,使其看起来像这样。100 / 14-34-018-09W4 / 00

sometimes they make look like this 4-9-62-3W6M in the database. 有时它们在数据库中看起来像这样的4-9-62-3W6M。 i need to format it so it looks like this 100/04-09-62-03W6/00. 我需要对其进行格式化,以使其看起来像这样100 / 04-09-62-03W6 / 00。 Some may or may not be in the format already and if they already have the 100/ or 102 in front for example then ignore that part. 有些格式可能已经采用或未采用这种格式,例如,如果它们前面已经有100 /或102,则可以忽略该部分。

If the first 3 numbers are missing, default to 100 or pad to 100. Replace the M with '' and the end after the / replace with 00 if nothing or pad 00. Also between in the middle between / and /, there are numbers 14-34 etc. if one of those numbers is 6. pad 0 to the left. 如果前三个数字丢失,则默认为100或填充为100。将M替换为'',将/的末尾替换为00(如果无则替换为00)或填充00。在/和/之间的中间,也有数字如果这些数字之一是6,则输入14-34,以此类推。在左边填充0。 so its a -06- instead of 6. 因此它是-06-而不是6。

Just wondering if someone can point me in the right direction or the easiest way to accomplish this. 只是想知道是否有人可以指出正确的方向或最简单的方法来实现这一目标。 thanks 谢谢

To be honest, I think I would approach this in steps. 老实说,我想我会逐步解决这个问题。 Before starting, save the table somewhere, so nothing inadvertent happens. 开始之前,将表保存在某个地方,这样就不会发生任何疏忽。

update t
    set lsd = lsd + '/00'
    where lsd not like '%/__';

update t
    set lsd = '100/' + lsd
    where lsd not like '%/%/__';

Then: 然后:

update t
    set lsd = stuff(lsd, 5, 0, '0')
    where lsd like '%/_-%';

And so on, for each position. 依此类推,针对每个职位。 That is build up the accurate string using where to fill in one position at a time. 这是建立使用精确的字符串where填写一次在一个位置。 This may take a few minutes, but it is probably a simpler and safer process than trying to do it all in one large query. 这可能要花费几分钟,但它可能比尝试在一个大型查询中完成所有操作更为简单和安全。

Check this out: 看一下这个:

DECLARE @dummy TABLE(ID INT IDENTITY,YourString VARCHAR(100));
INSERT INTO @dummy VALUES('4-9-62-3W6M')
                        ,('100/4-9-62-3W6M')
                        ,('4-9-62-3W6M/3')
                        ,('102/4-9-62-3W6M')
                        ,('5/4-9-62-3W6/5');

WITH Splitted AS
(
    SELECT 
           ID
          ,d.YourString 
          ,CAST('<x>' + REPLACE(REPLACE(d.YourString,'/','-'),'-','</x><x>') + '</x>' AS XML) AS TheXML
          ,CASE WHEN CHARINDEX('/',d.YourString)>0 AND CHARINDEX('/',d.YourString)<CHARINDEX('-',d.YourString) 
                THEN 1 ELSE 0 
           END AS HasPrefix
    FROM @dummy AS d
) 
,Parted AS
(
    SELECT *
          ,CASE WHEN HasPrefix=1 THEN TheXML.value('(/x)[1]','nvarchar(max)') 
                                 ELSE '100' END AS Prefix
          ,TheXML.value('(/x)[1+sql:column("HasPrefix")][1]','nvarchar(max)') AS Part1
          ,TheXML.value('(/x)[2+sql:column("HasPrefix")][1]','nvarchar(max)') AS Part2
          ,TheXML.value('(/x)[3+sql:column("HasPrefix")][1]','nvarchar(max)') AS Part3
          ,TheXML.value('(/x)[4+sql:column("HasPrefix")][1]','nvarchar(max)') AS Part4
          ,TheXML.value('(/x)[5+sql:column("HasPrefix")][1]','nvarchar(max)') AS PostFix
    FROM Splitted
)
SELECT REPLACE(STR(Prefix,3),' ','0') + '/'
      +REPLACE(STR(Part1,2),' ','0') + '-'
      +REPLACE(STR(Part2,2),' ','0') + '-'
      +REPLACE(STR(Part3,2),' ','0') + '-'
      +CASE WHEN RIGHT(Part4,1)='M' THEN LEFT(Part4,LEN(Part4)-1) ELSE Part4 END + '/'
      +ISNULL(REPLACE(STR(PostFix,2),' ','0'),'00')
FROM Parted

The result 结果

100/04-09-62-3W6/00
100/04-09-62-3W6/00
100/04-09-62-3W6/03
102/04-09-62-3W6/00
005/04-09-62-3W6/05

What is going on? 到底是怎么回事?

After inserting some test data into a mock-up table I use one CTE to split your string at the hyphens. 将一些测试数据插入模型表后,我使用一个CTE在连字符处拆分字符串。 Before this, the slashes are replaced with hyphens, so we get each part separately. 在此之前,将斜杠替换为连字符,因此我们分别获得每个部分。

A flag HasPrefix tells us, whether the given code has a prefix (like 100/ or not). HasPrefix标志告诉我们,给定的代码是否带有前缀(例如100/ )。 We use this flag in the second CTE where we retrieve the parts out of the splitted string as add-parameter to find the actual position. 我们在第二个CTE中使用此标志,在该CTE中,我们从分割的字符串中检索出部分作为添加参数,以查找实际位置。

The final SELECT will use STR() and REPLACE for the padding and will concatenate the parts to one single string. 最终的SELECT将使用STR()REPLACE进行填充,并将这些部分连接为一个字符串。

If you want you can set a SELECT * FROM at the end to see all the intermediate steps. 如果需要,可以在最后设置SELECT * FROM以查看所有中间步骤。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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