Ответ 1
Вам нужно заменить запятую на период:
CAST(REPLACE(column, ',', '.') AS FLOAT)
SQL Server
выводит десятичный разделитель, определенный с помощью локали, но не выводит ничего, кроме периода в CAST
, на числовые типы.
Предполагая следующие данные:
Column1 (data type: varchar(50))
--------
11.6
-1
1,000
10"
Non-Numeric String
У меня есть запрос, который вытаскивает данные из этого столбца и хотел бы определить, является ли это число числом, а затем возвращает его как таковое в моем запросе. Поэтому я делаю следующее
SELECT CASE WHEN IsNumeric(Replace(Column1,'"','')) = 1 Then Replace(Column1,'"','') Else 0 End As NumericValue
SQL возвращает отчет: Ошибка конверсии при преобразовании значения varchar '11.6 'в тип данных int.
Почему? Я также попытался заставить это сделать:
SELECT CASE WHEN IsNumeric(Replace(Column1,'"','')) = 1 Then cast(Replace(Column1,'"','') as float) Else 0 End As NumericValue
И я получил: Ошибка преобразования типа данных varchar в float.
Вам нужно заменить запятую на период:
CAST(REPLACE(column, ',', '.') AS FLOAT)
SQL Server
выводит десятичный разделитель, определенный с помощью локали, но не выводит ничего, кроме периода в CAST
, на числовые типы.
Сначала конвертируйте строку в деньги, затем скрывайте ее в любом другом цифровом формате, так как тип денег всегда возвращает истинную числовую строку. Вы никогда не увидите ошибку.
Попробуйте следующее в своем запросе, и вы поймете, о чем я говорю. Оба вернутся 2345.5656. Тип данных Money округлен до 4 знаков после запятой, и, следовательно, литье вызывает округление до 4 знаков после запятой.
SELECT CAST('2,345.56556' as money), CAST('$2,345.56556' as money)
Cast (cast ('2,344' как деньги) как float) будет работать отлично или cast (cast ( "2 344" в качестве денег) в виде десятичной (7,2)) также будет работать.
Даже приведение (CAST ($ 2,345.56556 'как деньги) как int) будет отлично округлять его до ближайшего целого числа.
Есть много проблем с SQL isnumeric. Например:
select isnumeric('1e5')
Это приведет к возврату 1, но на многих языках, если вы попытаетесь преобразовать его в число, которое не получится. Лучшим подходом является создание собственной пользовательской функции с параметрами, которые необходимо проверить:
ISNUMERIC возвращает 1, когда входное выражение оценивается как действительное целое число, число с плавающей запятой, деньгами или десятичный тип;
Таким образом, проблема в том, что это допустимое число, но не допустимое значение int.
Кайл
Я думаю, что это решает проблему. Проблема заключается в том, что предложение ELSE инициализирует ваш результат INTEGER. Сделав явный приведение типов к FLOAT и добавив предложение Quassnoi, он работает.
DECLARE @MyTable TABLE (Column1 VARCHAR(50))
INSERT INTO @MyTable VALUES('11.6')
INSERT INTO @MyTable VALUES('-1')
INSERT INTO @MyTable VALUES('1,000')
INSERT INTO @MyTable VALUES('10" ')
INSERT INTO @MyTable VALUES('Non-Numeric String')
SELECT CASE WHEN ISNUMERIC(REPLACE(Column1,'"','')) = 1 THEN REPLACE(REPLACE(Column1,'"',''), ',', '.') ELSE CAST(0 AS FLOAT) END
FROM @MyTable
С уважением,
Ливны
IsNumeric(' ')
также возвращает 1, но затем CAST, когда int взрывается. Брендан выше говорит о своей собственной функции. Он прав.
Это решение не работает во всех случаях (в частности, номера с деньгами и/или разделителями тысяч). Объедините представление экспоненты в конец числа, которое представлено строкой... ISNUMERIC() отлично работает. Примеры ниже:
-- CURRENT ISNUMERIC RESULTS
SELECT ISNUMERIC('11.6'); --1
SELECT ISNUMERIC ('-1'); --1
SELECT ISNUMERIC('1,000'); --1
SELECT ISNUMERIC('10"'); --0
SELECT ISNUMERIC('$10'); --1
-- NEW ISNUMERIC RESULTS
SELECT ISNUMERIC('11.6'+'e+00'); --1
SELECT ISNUMERIC ('-1'+'e+00'); --1
SELECT ISNUMERIC('1,000'+'e+00'); --0
SELECT ISNUMERIC('10"'+'e+00'); --0
SELECT ISNUMERIC('$10'+'e+00'); --0
Это, по крайней мере, стандартизирует формат использования функции REPLACE().
Я только что встретил эту проблему.
Вы можете попробовать это решение, если не возражаете об ограничении десятичной длины.
CONVERT(numeric, CONVERT(money, '.'))
ПРИМЕЧАНИЕ.