生成顺序客户端编号

时间:2018-01-18 13:12:24

标签: sql sql-server azure-sql-database

我有一个基于客户端的系统,需要以下列形式提供顺序客户编号。

第一个客户端将获得A001,然后每个新客户端将获得A999。一旦它到达A999,它将继续到B001-B999,依此类推,直到Z001-Z999,它将重置为AA001-AA999,依此类推。

有没有人看到如何实现这一目标的方法?

3 个答案:

答案 0 :(得分:2)

我使用简单整数作为键和存储过程(或计算列)转换为您想要的格式。 我本质上不是数字操作,请检查这个计算格式的SQL。

假设您的开头不超过2个字母,因此客户端数量不足26 * 26 * 1000。

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <input type="text" class="b"><br>
    <div class="d" style="display: none;">
    I want to disappear
    <input type="text" class="a">
    </div>

返回表格:

$('input.typeahead').typeahead({
    hint: true,
    highlight: false,
    minLength: 1
  }, 
  {
    name: 'country',
    displayKey: 'value',
    source: substringMatcher(countries),
    limit: Number.MAX_VALUE
});

答案 1 :(得分:2)

这将为您提供从A00​​1到ZZ999要求的确切数字。如果你想要更多的数字,你需要为第三个字母添加逻辑等。请注意,你不是每个字母都有1000个数字,这会让事情变得更加尴尬。

WITH Numbers AS (
    SELECT 1 AS number
    UNION ALL
    SELECT number + 1 AS number FROM Numbers WHERE number < 701298)
SELECT 
    number,
    CASE WHEN number > 25974 THEN CHAR(64 + (number - 1) / 25974) ELSE '' END --This is the first letter (optional)
        + CHAR(65 + ((number - 1) / 999) % 26) --This is the second letter
        + FORMAT(CASE WHEN number < 1000 THEN number ELSE CASE WHEN number % 999 = 0 THEN 999 ELSE number % 999 END END, 'd3') --This is the three digit number
    AS client_id
FROM 
    Numbers 
OPTION (MAXRECURSION 0);

数字CTE只是为了获得合适数量的数字(1-701,298)。一旦我拥有它们,我需要在第二个字母改变(每999个数字)或第一个字母改变(每个26 * 999 = 25974个数字)时找到边界。请注意,第一个字母在需要之前被禁止。

这为您提供了27 * 26 * 999客户端ID(第一个字母可以为空白或A-Z = 27个选项,第二个字母可以是A-Z = 26个选项,数字可以是001-999 = 999个选项)。这是一个总共701,298个客户ID。

我建议您使用IDENTITY列或SEQUENCE来获取&#34;内部&#34; id(可能是主键候选者),然后使用函数从此数字计算客户端ID。这对于多个用户等更安全。您可以使用计算列,但这是一个相当大的开销?

答案 2 :(得分:0)

评论中的例子:(可能不是答案,因为它很长而贴在这里)

    CREATE SEQUENCE Numbers 
    INCREMENT BY 1 
    MINVALUE 1
    MAXVALUE 999
    CYCLE
    ;


--DROP TABLE test_DL
      Create table test_DL
    (
     VendorName varchar(50),
     VendorId as LeadingCharacters + CAST(FORMAT(TailingNumbers,'000') as VARCHAR(10)),
     LeadingCharacters VARCHAR(50),
     TailingNumbers INT DEFAULT(NEXT VALUE FOR Numbers),
     [Counter] INT IDENTITY(1,1)
     )

--ALTER SEQUENCE Numbers RESTART WITH 1

DECLARE @CONTROL INT = 0

WHILE (@CONTROL < 250)
BEGIN

INSERT INTO test_DL (VendorName)
VALUES ('THIS'),('IS'),('AN'),('EXAMPLE')

SET @CONTROL = @CONTROL + 1

END

;
WITH CTE
AS
(
SELECT *, ROW_NUMBER()OVER(ORDER BY [Counter],TailingNumbers) as RowNumber
FROM test_DL
)

UPDATE CTE
SET LeadingCharacters = CASE WHEN RowNumber <= 999 THEN 'A' WHEN 999 < RowNumber AND RowNumber < 2* 999 THEN 'B' END --The MOST ANNOYING PART is here, you need to manually category all the possibles


SELECT * FROM test_DL  --Run this to check the result

对于将来的更新,上述方法将非常愚蠢。请给你一些想法lol