SQL - 基于存储为VARCHAR的10位整数创建唯一AlphaNumeric

时间:2011-07-26 22:02:52

标签: sql hex varchar alphanumeric

我正在尝试模拟客户端在Excel中生成的SQL函数。实际上,它们具有唯一的10位数字值(VARCHAR)作为其企业数据库系统之一的主键。在另一个数据库中,它们需要唯一的5位字母数字标识符。他们希望5位数的字母数字值代表10位数字。所以他们在excel中做的是将10位数字分成对,然后将这些对中的每一对转换为十六进制值,然后将它们拼接在一起。

EXCEL等式是:

  

= IF(VALUE(MID(A2,1,4))大于0,DEC2HEX(VALUE(MID(A2,3,2)))及DEC2HEX(VALUE(MID(A2,5,2)) )及DEC2HEX(VALUE(MID(A2,7,2)))及DEC2HEX(VALUE(MID(A2,9,2))),DEC2HEX(VALUE(MID(A2,5,2)))及DEC2HEX(VALUE(MID(A2,7,2)))及DEC2HEX((VALUE(MID(A2,9,2)))))

我需要SQL的等价物。当然,如果有人在那里知道一个更好的方法来实现他们的基于10位数字的“5位字母数字标识符”的目标,我会全力以赴。

ADDED 8/2/2011

首先,谢谢给大家回复。很高兴看到人们愿意帮助甚至享受它!基于所有的回复,我很容易告诉我的客户他们的意图是合理的,只有他们的方法是不对的。我还想推荐一个解决方案。所以挑战仍然存在,只是稍作修改:

CHALLENGE:在SQL中,取一个10位数的唯一NUMERIC字符串,并尽可能少地用字符表示。结果字符串也必须是唯一的。

请注意,10位数字符串中的前3-4个字符可能为零,并且可以剥离它们以缩短生成的字母数字字符串。不是必需的,但也许有帮助。

3 个答案:

答案 0 :(得分:2)

这个问题本质上是不可能的。您有一个10位数字值要转换为5位字母数字值。由于有10个数字字符,这意味着您的10位数字有10 ^ 10 = 10 000 000 000个唯一值。由于有36个字母数字字符(26个字母+10个数字),因此您的5位数字有36 ^ 5 = 60 466 176个唯一值。你不能将一组100亿个元素映射到一个大约6000万的集合中。

现在,让我们仔细看看客户端代码的作用:

  

所以他们在excel中做的是将10位数字拆分成对,然后将这些对中的每一对转换为十六进制值,然后将它们拼接在一起。

这不是100%准确。 excel代码从不使用前2位数,但对剩余的8执行此操作。此算法存在两个主要问题,可能不是直观明显的:

  1. 两个10位数字可以映射到相同的5位数字。考虑数字1000000117和1000001701.1000000117的后四位数被映射到1 11,其中1000001701的最后四位数被映射到11 1.这导致两者都映射到00111。

  2. 5位数字甚至可能不会是5位数!例如,1000001616被映射到001010。

  3. 那么,什么是可能的解决方案?好吧,如果你不在乎这个5位数字是否唯一,在MySQL你可以使用类似的东西:

    hex(<NUMERIC VALUE> % 0xFFFFF)
    

答案 1 :(得分:1)

10 ^ 10 base 2的对数是33.219280948874

> return  math.log(10 ^ 10) / math.log(2)
33.219280948874
> = 2 ^ 33.21928
9999993422.9114

因此,表示此数字需要34位。在十六进制中,这将需要34/4 = 8.5个字符,远远超过5个。

> return  math.log(10 ^ 10) / math.log(16)
8.3048202372184

Excel宏忽略10个字符串的前4个(或6个)字符。

您可以尝试使用base 36而不是16进行编码。这将使您达到7个字符或更少。

> return  math.log(10 ^ 10) / math.log(36)
6.4254860446923

热门的base 64编码可以让您获得6个字符

> return  math.log(10 ^ 10) / math.log(64)
5.5365468248123

即使Ascii85编码也不会让你失望。

> return  math.log(10 ^ 10) / math.log(85)
5.1829075929158

你需要100基数才能达到5个字符

> return  math.log(10 ^ 10) / math.log(100)
5

没有100个可打印的ASCII字符,所以这不会起作用,正如zkhr所解释的那样,除非你愿意超越ASCII。

答案 2 :(得分:0)

我发现你的问题很有意思(虽然我并不认为你知道答案) - 我为了你的兴趣而搜索了一些内容,并发现这可能会对你有所帮助http://dpatrickcaldwell.blogspot.com/2009/05/converting-decimal-to-hexadecimal-with.html