0

My Table structure is

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

now i wants to increment the no field data based on the type.

for example for type1 the next no is a4

and

for numeric only I am using the following code

SELECT ISNULL(Max(No),0)+1 AS No FROM table

but how to do it for with Alphabets in SQL Server 2005

4

3 に答える 3

1

プレフィックスが 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

noただし、テーブルにない型 (たとえば「type4」) に対してnext を生成しようとすると、機能しません。それを可能にするには、各タイプのプレフィックスが指定されている別のテーブルが必要になる場合があります。

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」を超えないようにするため)。

于 2013-08-04T21:23:55.493 に答える
0

Noまず、列に UNIQUE インデックスが必要です。

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 はテーブル/パーティション レベルでロックをエスカレートします。

于 2013-08-03T10:10:48.287 に答える
0

のようなものを試してください

SELECT ISNULL(Max(No),0)+1 AS No FROM table group by type
于 2013-08-03T04:53:23.673 に答える