T-SQL通过字母数字键计算最大值

时间:2019-02-21 10:09:42

标签: sql sql-server tsql

我有一个customers表,其中包含由5个字母和3个数字组成的字母数字键。

例如,我尝试按顺序每5个字母计算下一个3位数字:

示例键

ALPHA001
ALPHA002
NUMBE001
NUMBE002
NUMBE003
PREST001
PREST002
PREST003
PREST004
PREST005

从上面的键列表中,我想返回每个唯一的5个字母的键的最大值。即

返回值

ALPHA002
NUMBE003
PREST005

5 个答案:

答案 0 :(得分:4)

首先:不要在一个列中存储多个值。应该将密钥和运行编号存储在单独的列中,并将它们组合在一起仅用于显示目的...

尝试一下

DECLARE @mockupTable TABLE(ID INT IDENTITY,YourKey VARCHAR(100));
INSERT INTO @mockupTable VALUES
 ('ALPHA001')
,('ALPHA002')
,('NUMBE001')
,('NUMBE002')
,('NUMBE003')
,('PREST001')
,('PREST002')
,('PREST003')
,('PREST004')
,('PREST005');

WITH cte AS
(
SELECT *
      ,ROW_NUMBER() OVER(PARTITION BY LEFT(YourKey,5) ORDER BY CAST(RIGHT(YourKey,3) AS INT) DESC) AS PartitionedRowNumber 
FROM @mockupTable
)
SELECT *
FROM cte
WHERE PartitionedRowNumber =1;

结果

ID  Key
2   ALPHA002
5   NUMBE003
10  PREST005

答案 1 :(得分:1)

您可以使用row_number()

select top (1) with ties t.*
from table t
order by row_number() over (partition by left(col, patindex('%[0-9]%', col)) order by col desc);

如果字母是固定的,则只需使用left()

order by row_number() over (partition by left(col, 5) order by col desc);

答案 2 :(得分:1)

  

我正在尝试按顺序为每5个数字计算下一个3位数字   字母

这应该做到:

SELECT CONCAT(LEFT(k, 5), FORMAT(MAX(RIGHT(k, 3)) + 1, '000'))
FROM (VALUES
    ('ALPHA001'),
    ('ALPHA002'),
    ('NUMBE001'),
    ('NUMBE002'),
    ('NUMBE003'),
    ('PREST001'),
    ('PREST002'),
    ('PREST003'),
    ('PREST004'),
    ('PREST005')
) tests(k)
GROUP BY LEFT(k, 5)

答案 3 :(得分:0)

您可以使用GROUP BYMAX进行此操作:

SELECT  KeyPrefix = LEFT(ExampleKey, 5),
        NextKey = CONCAT(LEFT(ExampleKey, 5), 
                        RIGHT(CONCAT('000', MAX(CONVERT(INT, RIGHT(ExampleKey, 3))) + 1), 3))
FROM    (VALUES
            ('ALPHA001'), ('ALPHA002'), ('NUMBE001'), ('NUMBE002'), ('NUMBE003'), 
            ('PREST001'), ('PREST002'), ('PREST003'), ('PREST004'), ('PREST005')
        ) t (ExampleKey)
GROUP BY LEFT(ExampleKey, 5);

主要操作如下:

  1. 获取键的数字部分:RIGHT(ExampleKey, 3)
  2. 将其转换为整数:CONVERT(INT, <output from 1>)
  3. 找到密钥类型的最大值,然后添加1:MAX(<output from 2>) + 1
  4. 用零填充:RIGHT(CONCAT('000', MAX(<output from 3>), 3)
  5. 连接原始前缀:CONCAT(LEFT(ExampleKey, 5), <output from 4>)

但是我强烈建议将其存储在两列中,然后使用计算列进行组合:

CREATE TABLE dbo.T
(
    KeyPrefix CHAR(5) NOT NULL,
    KeySequence INT NOT NULL,
    TKey AS CONCAT(KeyPrefix, RIGHT(CONCAT('000', KeySequence), 3))
);

然后您的查询变得更加简单:

SELECT  KeyPrefix, 
        KeySequence = MAX(KeySequence) + 1,
        TKey = CONCAT(KeyPrefix, RIGHT(CONCAT('000', MAX(KeySequence) + 1), 3))
FROM    (VALUES
            ('ALPHA', 1), ('ALPHA', 2), ('NUMBE', 1), ('NUMBE', 2), ('NUMBE', 3), 
            ('PREST', 1), ('PREST', 2), ('PREST', 3), ('PREST', 4), ('PREST', 5)
        ) t (KeyPrefix, KeySequence)
GROUP BY KeyPrefix;

尽管值得注意的是,您实际上根本不需要像上面在TKey列中所做的那样重建密钥,但是您只需要最大密钥序列即可。

答案 4 :(得分:0)

使用此查询。

        GO
        ;WITH cte AS
        (
        SELECT ROW_NUMBER() OVER(PARTITION BY LEFT(YourKey,patindex('%[0-9]%', YourKey)) ORDER BY CAST(RIGHT(YourKey,patindex('%[A-Z]%', YourKey)) AS INT) DESC) AS rr , YourKey FROM @mockupTable
        )
        SELECT YourKey FROM cte WHERE rr =1;

        GO