博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
T-SQL: 用26个字母表示10000条不重复的编号
阅读量:5020 次
发布时间:2019-06-12

本文共 3421 字,大约阅读时间需要 11 分钟。

看到园子里一位朋友用newid()写的,():

insert into T select top 10000         replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(lower(left(replace(newid(),                                                               '-', ''), 20)),                                                               '0', 'a'), 1,                                                               'b'), 2, 'c'), 3,                                                               'd'), 4, 'e'), 5,                                                 'f'), 6, 'g'), 7, 'h'), 8, 'i'),                 9, 'j') as col from    sys.all_columns ,         sys.all_objects

这里newid()产生一个GUID, 形如"F6BCE480-834B-4FB9-B905-B568B9F9C7A3", (32个字母和数字加4条横线), 理论上是没有重复的. 问题在于, 当把其中的数字转换成字母之后, 产生的字母序列中一个字母可能对应GUID的一个字母, 也可能对应的是一个数字. 换句话说, 当把这个字母序列"翻译"回GUID的时候, 它最多可以对应到2的32次方个不同的GUID, (拿计算器算了下: 4,294,967,296个). 这样先不说出现重复的概率大不大, 至少理论上不能保证说不出现重复的.

 

其实, 0到10000, 这数字本身就是不重复的, 干脆把他们转换成字母就好了. 这是方法一:

declare @n intset @n = 0;while @n<10000begin    print replace(replace(convert(varchar(5), @n), '0', 'a'), '1', 'b') ---replace('2', 'c')....    set @n = @n+1end

 

上面看到的是a, b, c...h, i, j十个字母的组合, 是不是可以用26个字母? 当然是可以的. 不妨把十进制转换成"二十六进制": a = 0, b = 1 .... z = 25. 那么, ba = 26. 好, 没问题, 可以这样:

declare @one int, @n int, @res varchar(5)set @n = 20 -- testif (@n = 0) set @res = 'a';else set @res = ''while @n > 0begin    set @one = @n%26    set @res = CHAR(@one+97) + @res    set @n = @n/26endprint @res

上面解决了"二十六进制"的问题. 我们还知道while循环是可以嵌套的, 于是, 可以用"二十六进制"来表示10000个编号. 方法二:

declare @n intset @n = 0while @n < 10000begin    declare @one int, @num int, @res varchar(5)    set @num = @n    if (@num = 0) set @res = 'a'    else set @res = ''    while @num>0    begin        set @one=@num%26        set @res = CHAR(@one+97) + @res        set @num = @num/26    end        print @res        set @n = @n+1end

 

另外, SQL SERVER 2008开始提供表值函数:

select ch from    (      values        ('a'), ('b'), ('c'), ('d'), ('e'), ('f'), ('g'),        ('h'), ('i'), ('j'), ('k'), ('l'), ('m'), ('n'),        ('o'), ('p'), ('q'), ('r'), ('s'), ('t'),        ('u'), ('v'), ('w'), ('x'), ('y'), ('z')    ) as char_table(ch)

不妨考虑用26个字母作个交叉连接, 26*26*26 = 17576, 三张表足够了. 方法三:

with chars as ( select ch from    (      values        ('a'), ('b'), ('c'), ('d'), ('e'), ('f'), ('g'),        ('h'), ('i'), ('j'), ('k'), ('l'), ('m'), ('n'),        ('o'), ('p'), ('q'), ('r'), ('s'), ('t'),        ('u'), ('v'), ('w'), ('x'), ('y'), ('z')    ) as char_table(ch)) select a.ch, b.ch, c.ch, (a.ch+b.ch+c.ch) as rnfrom chars as across join chars as bcross join chars as c-- resultsch   ch   ch   rn---- ---- ---- ----a    a    a    aaaa    b    a    abaa    c    a    acaa    d    a    ada....

可以看到它从第二列开始递增, 我们想让它从第三列开始:

with chars as ( select ch from    (      values        ('a'), ('b'), ('c'), ('d'), ('e'), ('f'), ('g'),        ('h'), ('i'), ('j'), ('k'), ('l'), ('m'), ('n'),        ('o'), ('p'), ('q'), ('r'), ('s'), ('t'),        ('u'), ('v'), ('w'), ('x'), ('y'), ('z')    ) as char_table(ch)),bc as (select c1.ch as chb, c2.ch as chc from chars as c1 cross join chars as c2),abc as (select ch as cha, chb, chc from chars cross join bc) select top 10000 cha, chb, chc, (cha+chb+chc) as rn from abc-- resultscha  chb  chc  rn---- ---- ---- ----a    a    a    aaaa    a    b    aaba    a    c    aaca    a    d    aad....

好了, 吃饭去啦!

转载于:https://www.cnblogs.com/Freeway/archive/2013/03/30/chars_for_number.html

你可能感兴趣的文章
简化工作流程 10款必备的HTML5开发工具
查看>>
c++ 调用外部程序exe-ShellExecuteEx
查看>>
Java进击C#——语法之知识点的改进
查看>>
IdentityServer流程图与相关术语
查看>>
BirdNet: a 3D Object Detection Framework from LiDAR information
查看>>
icon fonts入门
查看>>
【Django】如何按天 小时等查询统计?
查看>>
HDU2191(多重背包)
查看>>
测试用例(一)
查看>>
【转】 mysql反引号的使用(防冲突)
查看>>
邮件中的样式问题
查看>>
AJAX 状态值与状态码详解
查看>>
php面向对象编程(oop)基础知识示例解释
查看>>
1.在数组中找到与给定总和的配对
查看>>
树的子结构
查看>>
关于根据Build Platform或者OS 加载x86或者x64 dll的问题
查看>>
程序员高效开发的几个技巧
查看>>
js-权威指南学习笔记19.2
查看>>
hexo 搭建博客
查看>>
关于 UIWebView 几个高级用法
查看>>