SQL - Создать уникальный буквенно-цифровой символ на основе 10-значного целого числа, сохраненного как VARCHAR - PullRequest
2 голосов
/ 27 июля 2011

Я пытаюсь эмулировать функцию в SQL, которую клиент создал в Excel.По сути, они имеют уникальное 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(ЗНАЧЕНИЕ (MID (A2,7,2))) & DEC2HEX (ЗНАЧЕНИЕ (MID (A2,9,2))), DEC2HEX (ЗНАЧЕНИЕ (MID (A2,5,2))) & DEC2HEX (ЗНАЧЕНИЕ (MID (А2,7,2))) & DEC2HEX ((VALUE (MID (A2,9,2)))))

Мне нужен SQL-эквивалент этого.Конечно, если кто-то знает лучший способ достичь своей цели «5-значный буквенно-цифровой идентификатор», основанный на 10-значном числе, я весь в ушах.

ДОБАВЛЕНО 02.08.2011

Прежде всего, спасибо всем за ответы.Приятно видеть людей, готовых помочь и даже наслаждающихся этим!Основываясь на всех ответах, я склонен сказать своему клиенту, что они намерены, это здраво, только их метод не подходит.Я также хотел бы рекомендовать решение.Таким образом, проблема остается, только слегка измененная:

ВЫЗОВ: В SQL возьмите уникальную ЦИФРОВУЮ 10-значную строку и представьте ее АЛЬФАНЕРИЧЕСКИ как можно меньше символов.Результирующая строка также должна быть уникальной.

Обратите внимание, что первые 3-4 символа в 10-значной строке, вероятно, будут нулями, и что они могут быть удалены, чтобы сократить результирующую буквенно-цифровую строку.Не обязательно, но, возможно, полезно.

Ответы [ 3 ]

2 голосов
/ 27 июля 2011

Эта проблема по своей сути невозможна. У вас есть 10-значное числовое значение, которое вы хотите преобразовать в 5-значное буквенно-цифровое значение. Поскольку имеется 10 числовых символов, это означает, что для вашего 10-значного числа имеется 10 ^ 10 = 10 000 000 000 уникальных значений. Поскольку имеется 36 буквенно-цифровых символов (26 букв + 10 цифр), для вашего 5-значного числа имеется 36 ^ 5 = 60 466 176 уникальных значений. Вы не можете отобразить набор из 10 миллиардов элементов в набор из примерно 60 миллионов.

Теперь давайте подробнее рассмотрим, что делает код вашего клиента:

Итак, в Excel они разбили 10-значное число на пары, затем преобразовали каждую из этих пар в шестнадцатеричное значение, а затем соединили их вместе.

Это не на 100% точно. Код Excel никогда не использует первые 2 цифры, но выполняет эту операцию с оставшимися 8. С этим алгоритмом связаны две основные проблемы, которые могут быть неочевидными:

  1. Два 10-значных числа могут быть сопоставлены с одним и тем же 5-значным числом. Рассмотрим числа 1000000117 и 1000001701. Последние четыре цифры 1000000117 сопоставляются с 11, где последние четыре цифры 1000001701 сопоставляются с 11 1. Это приводит к тому, что оба сопоставляются с 00111.

  2. 5-значное число может даже не оказаться 5-значным! Например, 1000001616 сопоставляется с 001010.

Итак, что является возможным решением? Что ж, если вам все равно, является ли это пятизначное число уникальным или нет, в MySQL вы можете использовать что-то вроде:

hex(<NUMERIC VALUE> % 0xFFFFF)
1 голос
/ 27 июля 2011

Лог 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 игнорирует первые 4 (или 6) символа строки из 10 символов.

Вы можете попробовать кодирование в 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.

0 голосов
/ 27 июля 2011

Я нашел ваш вопрос интересным (хотя я не претендую на то, что знаю ответ) - Я немного погуглил для вас из интереса и нашел это, которое может помочь вам http://dpatrickcaldwell.blogspot.com/2009/05/converting-decimal-to-hexadecimal-with.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...