2011-07-26 52 views
2

我試圖模擬客戶端在Excel中生成的SQL中的函數。實際上,它們在其企業數據庫系統之一中具有唯一的10位數值(VARCHAR)作爲主鍵。在另一個數據庫中,它們需要一個唯一的5位字母數字標識符。他們希望這個5位字母數字值是10位數字的表示。所以他們在Excel中做的是將10位數字分成兩對,然後將這些對中的每一個轉換成十六進制值,然後將它們重新拼接在一起。SQL - 基於存儲爲VARCHAR的10位整數創建唯一的AlphaNumeric

的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,7,2))) 5,2)))& DEC2HEX(VALUE(MID(A2,7,2)))& DEC2HEX((VALUE(MID(A2,9,2)))))

我需要的SQL相當於這個的。當然,如果有人在那裏知道更好的方法來完成基於10位數字的「5位數字字母數字標識符」的目標,那麼我就是耳朵。

ADDED 2011/8/2

首先,謝謝給大家的答覆。很高興看到人們願意幫助,甚至享受它!基於所有的反應,我傾向於告訴我的客戶他們的意圖是健全的,只有他們的方法是不成問題的。我也想推薦一個解決方案。所以挑戰依然存在,只是稍作修改:

挑戰:在SQL中,取一個10位數獨特的NUMERIC字符串,並用儘可能少的字符在字符串中表示它。生成的字符串也必須是唯一的。

請注意,10位字符串中的前3-4個字符可能爲零,並且可能會剝離它們以縮短生成的字母數字字符串。不是必需的,但可能有幫助。

回答

1

的10^10個鹼基的日誌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編碼,不會讓你到5。

> 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

這個問題本質上是不可能的。你有一個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.

那麼,什麼是可能的解決方案?那麼,如果你不關心這個5位數是否唯一,在MySQL中你可以使用類似於:

hex(<NUMERIC VALUE> % 0xFFFFF) 
相關問題