我想在插入数据期间基于两列生成自定义的唯一密钥(复合密钥),并发处理的人数与那里尝试创建账单的用户一样多。
Billno应该以B01到B02,B03 ... N开头,直到付款类型和年份更改为止。
在完全插入后,这是期望的数据到表中。
BillId PaymentType Year BillNo
1 Card 2018 B01
2 Card 2018 B02
3 Card 2019 B01
4 Cash 2018 C01
5 Cash 2018 C02
6 Cash 2018 C03
7 PayTM 2019 P01
注意:我已经通过更新和插入触发器来完成此操作,但是由于性能问题,正在寻找其他选择。
如果有人能解决问题,我表示感谢。
答案 0 :(得分:0)
您可以使用ROW_NUMBER
来生成编号,并使用DENSE_RANK
来生成字母:
;WITH WindowFunctions AS
(
SELECT
T.*,
RowNumber = ROW_NUMBER() OVER (
PARTITION BY
PaymentType,
Year
ORDER BY
BillId),
DenseRank = DENSE_RANK() OVER (ORDER BY PaymentType, Year)
FROM
YourTable AS T
)
SELECT
T.*,
BillNo = CHAR(64 + T.DenseRank) + RIGHT('0' + CONVERT(VARCHAR(10), T.RowNumber), 2)
FROM
WindowFunctions AS T
请注意可能的字母数量,使用CHAR
函数可能会降低效果。
结果:
BillID PaymentType Year RowNumber DenseRank BillNo
1 Card 2018 1 1 A01
2 Card 2018 2 1 A02
3 Card 2019 1 2 B01
4 Cash 2018 1 3 C01
5 Cash 2018 2 3 C02
6 Cash 2018 3 3 C03
7 PayTM 2019 1 4 D01
但是,仅当您考虑将整个集合放在同一SELECT
上时,此方法才有效。一旦加载了表并设置了BillNo
,您将无法生成下一个BillNo
,除非您考虑将先前的记录与另一个SELECT
一起使用,这会变得很棘手。 / p>
如果您确实需要1列键,建议您生成一个不依赖于其他/先前记录的ID,例如将PaymentType
与BillId
混合在一起。