我的表结构是
id type no amount
1 type1 a1 1000
2 type1 a2 2000
3 type2 b1 3000
4 type3 c1 4000
5 type1 a3 5000
6 type2 b2 6000
7 type2 b3 7000
8 type3 c2 8000
现在我想根据no
增加type
字段数据。
例如type1
,下一个是a4
和
仅限数字我使用以下代码
SELECT ISNULL(Max(No),0)+1 AS No FROM table
但如何在SQL Server 2005中使用Alphabets
答案 0 :(得分:1)
假设前缀是单字符长度,您可以尝试以下操作:
;with cte as (
select type, typePrefix = left(no, 1), typeNum = right(no, len(no) - 1)
from TableName
)
select typePrefix + cast(isnull(max(typeNum), 0) + 1 as varchar(10))
from cte
where type = 'type1'
group by typePrefix
但如果您尝试为不在表格中的类型(例如“type4”)生成下一个no
,则无效。要允许它,您可能需要一个单独的表,其中指定了每种类型的前缀:
create table TypePrefixes (type varchar(50), prefix varchar(10))
insert into TypePrefixes values ('type1', 'a')
insert into TypePrefixes values ('type2', 'b')
insert into TypePrefixes values ('type3', 'c')
insert into TypePrefixes values ('another_type', 'd')
--etc.
在这种情况下,获取下一个no
的语句将显示为:
select tp.prefix + cast(isnull(max(cast(right(t.no, len(t.no) - len(tp.prefix)) as int)), 0) + 1 as varchar(20))
from TableName t
right join TypePrefixes tp on tp.type = t.type
where tp.type = 'type4'
group by tp.prefix
此外,您可能只想为每条记录计算no
,例如:
;with cte as (
select *,
typeNum = row_number() over (partition by type order by id),
typePrefix = char(dense_rank() over (order by type) + ascii('a') - 1)
from TableName
)
select *, No2 = typePrefix + cast(typeNum as varchar(10))
from cte
但是,后者的表格中不同类型的数量有限,不应超过26(因此我们不能超过'z')。
答案 1 :(得分:0)
尝试类似
的内容SELECT ISNULL(Max(No),0)+1 AS No FROM table group by type
答案 2 :(得分:0)
首先,您需要No
列上的唯一索引:
CREATE UNIQUE INDEX IUN_MyTable_On
ON MySchema.MyTable(On);
GO
此唯一索引将阻止重复值,但也会帮助进行以下查询。
其次,您可以使用此脚本为给定的字母生成下一个No
:
DECLARE @Chr CHAR(1);
SET @Chr='A';
BEGIN TRY
BEGIN TRANSACTION;
DECLARE @LastId INT;
DECLARE @NewNo VARCHAR(...); -- Fill with No's max. length
-- Previous index will help this query
SELECT @LastId=MAX( CONVERT(INT,SUBSTRING(@LastNo,2,8000)) )
FROM MySchema.MyTable x WITH(UPDLOCK) -- It locks the rows to prevent a concurent session to generate the same value (No)
WHERE x.No LIKE @Chr+'%';
SET @NewNo=@Chr+CONVERT(VARCHAR(11),ISNULL(@LastId,0)+1);
-- Do whatever you want with the new value: ex. INSERT
INSERT INTO ... (No,...)
VALUES (@NewNo,...);
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
DECLARE @ErrMsg NVARCHAR(2000);
SET @ErrMsg=ERROR_MESSAGE();
IF @@TRANCOUNT>0
BEGIN
ROLLBACK;
END
RAISERROR(@ErrMsg,16,1);
END CATCH
注意#1:如果这是生成新值(@NewNo
)的唯一方法,则此解决方案应该是安全的。
注意#2:如果该SELECT查询至少获得了5000个锁,那么SQL Server将在表/分区级别上升锁。