sql以字符串和增量提取最右边的数字

时间:2019-10-07 11:11:36

标签: sql sql-server string tsql increment

我有类似

的交易代码
 "A0004", "1B2005","20CCCCCCC21"

我需要提取最右边的数字并将交易代码增加一个

"AA0004"----->"AA0005"
"1B2005"------->"1B2006"
"20CCCCCCCC21"------>"20CCCCCCCC22"

在SQL Server 2012中。

  • 未知的字符串长度
  • 正确的(n?)始终为数字

处理不重要的字符串和数字长度属于我的范围。 总是缺少一些逻辑。

LEFT(@a,2)+RIGHT('000'+CONVERT(NVARCHAR,CONVERT(INT,SUBSTRING( SUBSTRING(@a,2,4),2,3))+1)),3

3 个答案:

答案 0 :(得分:2)

首先,我想澄清一下:我完全同意a_horse_with_no_name和Jeroen Mostert对问题的评论。
您应该在每列,每周期存储一个数据点。

话虽如此,我确实意识到很多时候数据库结构都无法更改-因此,这是一种为您进行计算的可能方法。

首先,创建并填充示例表(在您将来的问题中为我们保存此步骤):

DECLARE @T AS TABLE 
(
    col varchar(100)
);

INSERT INTO @T (col) VALUES
('A0004'),
('1B2005'),
('1B2000'),
('1B00'),
('20CCCCCCC21');

(我添加了几个字符串作为您在问题中未提及的边缘案例)

然后,使用几个cross apply来减少代码重复,我想到了:

SELECT  col,
        LEFT(col, LEN(col) - LastCharIndex + 1) + 
        REPLICATE('0', LEN(NumberString) - LEN(CAST(NumberString as int))) + 
        CAST((CAST(NumberString as int) + 1) as varchar(100)) As Result
FROM @T
CROSS APPLY
(
    SELECT PATINDEX('%[^0-9]%', Reverse(col)) As LastCharIndex
) As Idx
CROSS APPLY 
(
    SELECT RIGHT(col, LastCharIndex - 1) As NumberString
) As NS

结果:

col         Result
A0004       A0005
1B2005      1B2006
1B2000      1B2001
1B00        1B01
20CCCCCCC21 20CCCCCCC22

LastCharIndex表示字符串中最后一个非数字字符的索引。 NumberString表示要递增的数字,它是一个字符串(保留前导零(如果存在的话))。

从那里开始,只需取字符串的左侧部分(即直到数字),然后将其连接到新计算的数字字符串,使用Replicate将加法结果精确地填充原始数字字符串具有的前导零的数量。

答案 1 :(得分:0)

尝试一下

DECLARE @test nvarchar(1000) ='"A0004", "1B2005","20CCCCCCC21"'
DECLARE @Temp AS TABLE (ID INT IDENTITY,Data nvarchar(1000))
INSERT INTO @Temp 
SELECT @test

;WITH CTE
AS
(
SELECT Id,LTRIM(RTRIM((REPLACE(Split.a.value('.' ,' nvarchar(max)'),'"',''))))  AS Data
,RIGHT(LTRIM(RTRIM((REPLACE(Split.a.value('.' ,' nvarchar(max)'),'"','')))),1)+1 AS ReqData
FROM
(
SELECT ID,
CAST ('<S>'+REPLACE(Data,',','</S><S>')+'</S>' AS XML) AS Data
FROM @Temp
) AS A
CROSS APPLY Data.nodes ('S') AS Split(a)
)
SELECT CONCAT('"'+Data+'"','-------->','"'+CONCAT(LEFT(Data,LEN(Data)-1),CAST(ReqData AS VARCHAR))+'"') AS ExpectedResult
FROM CTE

结果

ExpectedResult
-----------------
"A0004"-------->"A0005"
"1B2005"-------->"1B2006"
"20CCCCCCC21"-------->"20CCCCCCC22"

答案 2 :(得分:0)

STUFF(@X ,LEN(@X)-CASE PATINDEX('%[AZ]%',REVERSE(@X))当0则LEN(@X)ELSE PATINDEX('%[AZ]%',REVERSE(@X))- 1个END + 1 ,LEN((((RIGHT(@ X,CASE PATINDEX('%[AZ]%',REVERSE(@X))当0 THEN LEN(@X)ELSE PATINDEX('%[AZ]%',REVERSE(@X ))-1 END)/ @ N)+1) @N) ,(((RIGHT(@ X,CASE PATINDEX('%[AZ]%',REVERSE(@X))当0 THEN LEN(@X)ELSE PATINDEX('%[AZ]%',REVERSE(@X))时-1 END)/ @ N)+1) @N)

  • 仅处理数字字符串
  • 99变为100
  • mod(@N)增量