Кастинг научной нотации (из varchar -> числовой) в виде - PullRequest
15 голосов
/ 19 июля 2011

По причинам, которые я не могу помочь, у меня есть столбец varchar с данными, подобными следующим: 820.0E-12, 10.0E + 00.

Я хочу числовое значение. Итак, у меня есть тест запрос, который работает:

declare @d varchar(256)
set @d = '820.0E-12'
select 
   CASE 
      WHEN @d like '%E-%' THEN LTRIM(RTRIM(CAST(CAST(@d AS FLOAT) AS DECIMAL(18,18))))
      WHEN @d like '%E+%' THEN NULL
      ELSE @d
   END

Мой результат: 0.000000000820000000 (это то, что я хочу)

Я изменяю свой SQL для учета чисел> 0 (10.0E + 00) следующим образом:

WHEN @d like '%E+%' THEN CAST(@d AS FLOAT)

Мой результат меняется на: 8.2E-10 (это НЕ то, что я хочу)

Если я изменю @d='10.0E+00', тогда я получу 10 (что правильно).

У меня есть представление, что мне нужно сделать вывод из столбца varchar, который содержит научную запись, приведенный / преобразованный в десятичную (18,18).

Может кто-нибудь сказать мне, что здесь происходит сумасшествие?

Или, может быть, мой вопрос должен заключаться в том, как преобразовать / преобразовать столбец научной нотации varchar в десятичный вывод в представлении?

Мой первый оператор WHEN работает для чисел <0, но мне также нужно учитывать числа> 0. Когда я изменяю второй WHEN, чтобы включить CAST , он ломается / дает неправильный результат.

Ответы [ 3 ]

17 голосов
/ 19 июля 2011

Есть несколько разных проблем, которые собираются здесь одновременно.Давайте рассмотрим некоторые из них:

  1. Вы играете числа как ДЕСЯТИЧНЫЕ (18, 18).Это означает, что «дайте мне число, в котором есть ОБЩАЯ 18 символов, и 18 из них должны быть после десятичной дроби».Это прекрасно работает, если ваше число меньше 0 (что верно для всех E-номеров), но оно сломается, если вы попытаетесь использовать его для чисел> 0. Для чисел> 0 просто приведите как DECIMAL, не задавая ничего другого.

  2. В случае, когда вы добавляете «WHEN @d like '% E +%' THEN CAST (@d AS FLOAT)», вы получаете разные результаты для чисел <0, потому чтодвигатель неявно приводит результат к другому.Я не знаю правил о том, как sql-сервер решает привести результаты CASE, но, очевидно, внесение предложенного вами изменения приводит к тому, что движок изменяет его по-другому.Явное приведение этих результатов к десятичному типу решает проблему. </p>

  3. Вам необходимо последовательно обрабатывать результаты LTRIM и RTRIM.Вы можете либо добавить LTRIM и RTRIM к каждому заявлению, либо вы можете просто LTRIM и RTRIM результаты кейса.

Вот решение, которое должно полностью решить все:

SELECT
    LTRIM(RTRIM(CASE 
        WHEN @d like '%E-%' THEN CAST(CAST(@d AS FLOAT) AS DECIMAL(18,18))
        WHEN @d like '%E+%' THEN CAST(CAST(@d AS FLOAT) AS DECIMAL)
        ELSE @d
    END))
5 голосов
/ 21 декабря 2015

вы можете использовать ISO "реальный" тип данных


SELECT convert(numeric(18,18),convert(real,'820.0E-12'))
--OR with more precision
SELECT convert(numeric(18,18),convert(float(53),'820.0E-12'))
0 голосов
/ 06 марта 2017
mysql> select '820.0E-12' + 0, '10.0E+00' + 0;
+-----------------+----------------+
| '820.0E-12' + 0 | '10.0E+00' + 0 |
+-----------------+----------------+
|   0.00000000082 |             10 |
+-----------------+----------------+

То есть простое добавление 0 к varchar должно дать вам числовое значение.(ОК, сначала вам может понадобиться TRIM.)

По существу нет разумного варианта использования для m или n в FLOAT(m,n);просто объявите вещи FLOAT (примерно до 7 значащих цифр) или DOUBLE (примерно до 16).

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