有没有办法在SQL中用当前年份生成字母序列

问题描述

我们如何编写一个可以生成 'Sequence_Code' 的 sql 函数,如 AA,AB,AC....AZ。 BA,BB,BC.... 与每个“ID”的“Current_Year”的最后两位数字的组合。 按“Record_Date”排序

例如:如果第一行的 Current_Year 是 2019,那么 Sequence_Code 应该是 19AA。 我的表是 LoadData

Sequence_Code ID Current_Year Record_Date
NULL 310001 2019 2019-01-01
NULL 310002 2018 2018-02-22
NULL 310003 2020 2020-02-20
NULL 310004 2020 2020-02-10

预期输出为:

Sequence_Code ID Current_Year Record_Date
19AA 310001 2019 2019-01-01
18AB 310002 2018 2018-02-22
20AC 310003 2020 2020-02-20
公元20年 310004 2020 2020-02-10

解决方法

最简单的方法可能是生成所有组合并枚举它们:

with alpha as (
      select 'A' as alpha union all
      select 'B' as alpha union all
      . . .  -- continue for the rest of the letters
      select 'Z' as alpha
     ),alphas as (
      select concat(a1.alpha,a2.alpha) as alpha2,row_number() over (order by a1.alpha,a2.alpha) as seqnum
      from alpha a1 cross join
           alpha a2
     )
select current_year || alpha2.alpha2 as sequence_code,t.*
from (select t.*,row_number() over (partition by current_year order by record_date) as seqnum
      from LoadData t
     ) t left join
     alpha2 
     on t.seqnum = a2.seqnum;

注意:这里使用标准 SQL,因此功能可能有不同的语法,具体取决于数据库。

,

使用 ROW_NUMBER() 窗口函数和数学:

WITH cte AS (SELECT *,ROW_NUMBER() OVER (ORDER BY Record_Date) rn FROM LoadData)
SELECT RIGHT(Current_Year,2) + 
       CHAR(ASCII('A') + rn / 26 + CASE rn % 26 WHEN 0 THEN -1 ELSE 0 END) + 
       CHAR(ASCII('A') - 1 + CASE rn % 26 WHEN 0 THEN 26 ELSE rn % 26 END) Sequence_Code,ID,Current_Year,Record_Date
FROM cte
ORDER BY rn

如果要更新表的 Sequence_Code 列:

WITH cte AS (SELECT *,ROW_NUMBER() OVER (ORDER BY Record_Date) rn FROM LoadData)
UPDATE cte
SET Sequence_Code = RIGHT(Current_Year,2) + 
                    CHAR(ASCII('A') + rn / 26 + CASE rn % 26 WHEN 0 THEN -1 ELSE 0 END) + 
                    CHAR(ASCII('A') - 1 + CASE rn % 26 WHEN 0 THEN 26 ELSE rn % 26 END)

参见demo
结果:

> Sequence_Code |     ID | Current_Year | Record_Date
> :------------ | -----: | -----------: | :----------
> 18AA          | 310001 |         2018 | 2018-01-01 
> 19AB          | 310002 |         2019 | 2019-02-22 
> 20AC          | 310004 |         2020 | 2020-02-10 
> 20AD          | 310003 |         2020 | 2020-02-20