有什么方法可以生成当前年份的字母序列 SQL
Is there any way to generate Alphabetic Sequence with Current Year In SQL
我们如何编写一个 SQL 函数来生成 'Sequence_Code' 像 AA,AB,AC....AZ。 BA,BB,BC....每个 'ID' 的最后两位数 'Current_Year' 的组合。
按 'Record_Date'
排序
例如:如果第一行的Current_Year是2019,那么Sequence_Code应该是19AA。
我的 table 是 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
20AD
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()
window 函数和数学:
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
如果要更新 table 的第 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
我们如何编写一个 SQL 函数来生成 'Sequence_Code' 像 AA,AB,AC....AZ。 BA,BB,BC....每个 'ID' 的最后两位数 'Current_Year' 的组合。 按 'Record_Date'
排序例如:如果第一行的Current_Year是2019,那么Sequence_Code应该是19AA。 我的 table 是 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 |
20AD | 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()
window 函数和数学:
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
如果要更新 table 的第 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