我已经在nvarchar列中填充了一些字符串值。字符串的格式如下:
例如:16B,23G,128F,128M等......
我需要从这些中找出最大值,然后从代码中生成下一个值。获取最大项目的逻辑如下:
例如,上述系列中最大的字符串是128M。
现在我需要生成下一个序列。下一个字符串将有
任何人都可以让我知道哪种SQL可以获得所需的字符串。
答案 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
答案 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是列