用于在字母数字字符串中生成下一个序列的SQL代码

时间:2012-09-28 14:28:08

标签: sql sql-server tsql

我已经在nvarchar列中填充了一些字符串值。字符串的格式如下:

例如:16B,23G,128F,128M等......

我需要从这些中找出最大值,然后从代码中生成下一个值。获取最大项目的逻辑如下:

  1. 拿起编号最大的字符串。
  2. 如果是多个最大的数字,那么拿起字符串中最大的字母。
  3. 例如,上述系列中最大的字符串是128M。

    现在我需要生成下一个序列。下一个字符串将有

    1. 与最大的数字相同的数字,但字母表增加1. I.E. 128N
    2. 如果字母到达Z,则数字增加1,字母表为A. 例如,下一个128Z的字符串是129A。
    3. 任何人都可以让我知道哪种SQL可以获得所需的字符串。

5 个答案:

答案 0 :(得分:4)

如果您可以更改表定义(*),则将基本值保持为完全数字并且只是格式化为这些字符串会更容易:

create table T (
    CoreValue int not null,
    DisplayValue as CONVERT(varchar(10),(CoreValue / 26)+1) + CHAR(ASCII('A') + (CoreValue-1) % 26)
)
go
insert into T (CoreValue)
select ROW_NUMBER() OVER (ORDER BY so1.object_id)
from sys.objects so1,sys.objects so2
go
select * from T

结果:

CoreValue   DisplayValue
----------- ------------
1           1A
2           1B
3           1C
4           1D
5           1E
6           1F
....
22          1V
23          1W
24          1X
25          1Y
26          2Z
27          2A
28          2B
29          2C
....
9593        369Y
9594        370Z
9595        370A
9596        370B
9597        370C
9598        370D
9599        370E
9600        370F
9601        370G
9602        370H
9603        370I
9604        370J

因此,插入新值 就像从列中取MAX并添加1(假设可序列化隔离或类似,以处理多个用户)一样简单


(*)即使你不能改变你的表定义 - 我仍然会生成这个表。然后,您可以将其加入原始表格,并可以使用它对MAX列执行简单int,然后添加一个并查找要使用的下一个字母数字值。只需使用您期望使用的多个值填充它。

答案 1 :(得分:1)

假设:

CREATE TABLE MyTable
    ([Value] varchar(4))
;

INSERT INTO MyTable
    ([Value])
VALUES
    ('16B'),
    ('23G'),
    ('128F'),
    ('128M')
;

你可以这样做:

select top 1 
    case when SequenceChar = 'Z' then
        cast((SequenceNum + 1) as varchar) + 'A'
    else
        cast(SequenceNum as varchar) + char(ascii(SequenceChar) + 1)
    end as NextSequence
from (
    select Value, 
        cast(substring(Value, 1, CharIndex - 1) as int) as SequenceNum, 
        substring(Value, CharIndex, len(Value)) as SequenceChar
    from (
        select Value, patindex('%[A-Z]%', Value) as CharIndex
        from MyTable
    ) a
) b
order by SequenceNum desc, SequenceChar desc

SQL Fiddle Example

答案 2 :(得分:0)

假设您的列始终遵循您描述的格式(数字+ 1个字符后缀),您可以执行

WITH cte1 AS(
SELECT LEFT(your_column,LEN(your_column)-1) as num, 
RIGHT(your_column,1) as suffix
FROM your_table),
cte2 AS (SELECT MAX(num) as max_num FROM cte1)
SELECT 
 CASE c.max_suffix
  WHEN 'Z' THEN 'A'
  ELSE NCHAR(UNICODE(c.max_suffix)+1)
 END as next_suffix,

CASE c.max_suffix
 WHEN 'Z' THEN a.max_num+1
 ELSE a.max_num
END as next_num

FROM  cte2 a 
CROSS APPLY (SELECT MAX(suffix) as max_suffix FROM cte1 b WHERE b.num=a.max_num)c
;

我很确定还有其他方法可以做到这一点;此外,我的方法似乎不是最佳的,但我认为它会返回你需要的......

毫无疑问,如果您可以按照 Damien_The_Unbeliever 推荐的那样重新设计表格会更好。

答案 3 :(得分:0)

以下列格式生成字母数字字符串序列。 A B C ..... Y Z AA AB ...... AZ BA BB ..... BZ ...继续。

CREATE OR REPLACE FUNCTION to_az(in_num  number)

RETURN VARCHAR2

IS

 num          PLS_INTEGER    := TRUNC (in_num) - 1;
 return_txt     VARCHAR2 (1) := CHR (65 + MOD (num, 26));

BEGIN

 IF  num <= 25
 THEN
      RETURN     return_txt;
 ELSE
      RETURN     to_az (FLOOR (num / 26))
           || return_txt;
 END IF;
END to_az;

答案 4 :(得分:0)

Ms-sql函数用于生成字母数字下一个序列ID,例如&#39; P0001&#39; P0002&#39;等等。

ALTER FUNCTION NextProductID()
 returns varchar(20)
 BEGIN
    DECLARE  @NEXTNUMBER INT;
    DECLARE @NEXTPRODUCTID VARCHAR(20);
 SELECT @NEXTNUMBER=MAX( CONVERT(INT, SUBSTRING(PRODUCT_CODE,2,LEN(PRODUCT_CODE))))+1 FROM Product;
    --PRINT @NEXTNUMBER;
    SET @NEXTPRODUCTID=CONVERT(VARCHAR,@NEXTNUMBER)
    SELECT @NEXTPRODUCTID='P'+REPLICATE('0',6-LEN(@NEXTPRODUCTID)) + @NEXTPRODUCTID;
  return @NEXTPRODUCTID;
END

此处的产品是表名,product_code是列