SQL Server 2008: преобразование Varchar в числовое переполнение данных, возможно, из-за того, что некоторые являются диапазонами - PullRequest
0 голосов
/ 27 февраля 2010

Я работаю над запросом со столбцом varchar с именем ALCOHOL_OZ_PER_WK. Часть запроса включает в себя:

where e.ALCOHOL_OZ_PER_WK >= 14

и получите ошибки:

Ошибка арифметического переполнения при преобразовании varchar в числовой тип данных.

и: Ошибка преобразования типа данных varchar в числовой.

Если посмотреть на значения, которые на самом деле хранятся в столбце, то наибольшее значение близко к 100, но некоторые записи являются диапазонами:

9 - 12
1.5 - 2.5

Я бы хотел получить верхний предел (или, возможно, среднюю точку диапазона) для строк с записями, подобными этой, и иметь это значение, которое сравнивается с 14.

Каким будет (или) простой способ сделать это?

Как всегда, спасибо!

Ответы [ 4 ]

2 голосов
/ 27 февраля 2010

Ваша БД, очевидно, является результатом какого-то опроса и, похоже, содержит исходные данные опроса. Обычный способ - выполнить это через процесс ECCD (Извлечь, Очистить, Соответствовать, Доставить) и сохранить чистые и стандартизированные данные в отдельной базе данных (возможно, в хранилище), которую затем можно использовать для аналитики и создания отчетов.

Если у вас есть SSIS, используйте задачу профилирования данных, чтобы получить представление о типах строк, которые у вас там есть. Профиль шаблона столбца сообщает о наборе регулярных выражений в столбце строки, поэтому вы получите представление о том, что находится внутри этих строк. Если у вас нет SSIS, вы можете использовать eobjects DataCleaner , чтобы сделать то же самое.

Если вы не можете сохранить новую базу данных или хотя бы новую таблицу - как минимум добавьте числовой столбец в эту таблицу, а затем извлеките числовые значения из этих строк в новый столбец. Вы можете использовать «что-то еще» (SSIS, Pentaho Kettle, Python, VB, C #) для этого - в общем, T-SQL не очень хорош в обработке строк.

Я предполагаю, что это не единственный столбец с мусором внутри, поэтому любой анализ, который вы можете выполнить на этом, может быть бесполезным.

И если вы все еще думаете, что диапазоны являются единственной проблемой, этот пример может помочь:

Первые данные

DECLARE @myTable TABLE ( 
  AlUnits varchar(10)
  ) ;

INSERT  INTO @myTable
        (AlUnits )
VALUES  ( '10' )
,       ( '15' )
,       ( '20' )
,       ( '7 - 12' )
,       ( '3 - 5' )
;

Запрос разбивает записи на две группы, числовые и не числовые - предполагаемые диапазоны.

;
WITH  is_num
        AS ( SELECT CAST(AlUnits AS decimal(6, 2)) AS Units_LO
                   ,CAST(AlUnits AS decimal(6, 2)) AS Units_HI
             FROM   @myTable
             WHERE  ISNUMERIC(AlUnits) = 1
           ),
      is_not_num
        AS ( SELECT CAST( RTRIM(LTRIM(LEFT(AlUnits,
                          CHARINDEX('-', AlUnits) - 1)))
                        AS decimal(6,2)) AS Units_LO
                   ,CAST(RTRIM(LTRIM(RIGHT(AlUnits,
                               LEN(AlUnits)
                               - CHARINDEX('-', AlUnits))))
                        AS decimal(6,2)) AS Units_HI
             FROM   @myTable
             WHERE  ISNUMERIC(AlUnits) = 0
           )
  SELECT  Units_LO
         ,Units_HI
         ,CAST(( Units_LO + Units_HI ) / 2.0 AS decimal(6, 2)) AS Units_Avg
  FROM    is_num
  UNION ALL
  SELECT  Units_LO
         ,Units_HI
         ,CAST(( Units_LO + Units_HI ) / 2.0 AS decimal(6, 2)) AS Units_Avg
  FROM    is_not_num ;

Возвращает:

Units_LO    Units_HI    Units_Avg 
----------- ----------- ----------
10.00       10.00       10.00     
15.00       15.00       15.00     
20.00       20.00       20.00     
7.00        12.00       9.50      
3.00        5.00        4.00      
1 голос
/ 27 февраля 2010

Не уверен насчет простых способов.

Правильный способ - сохранить числа в двух столбцах: ALCOHOL_OZ_PER_WK_MIN и ALCOHOL_OZ_PER_WK_MAX.

0 голосов
/ 27 февраля 2010

«вероятно, потому что некоторые диапазоны» - вы понимаете, что «диапазон» не является типом данных SQL Server?У вас есть нечисловые данные, которые вы пытаетесь преобразовать в числовые данные, и у вас есть скалярное значение, которое вы сравниваете с не скалярным значением.

В этой базе данных есть некоторые проблемы.

0 голосов
/ 27 февраля 2010

Как вы говорите, вам нужно вычислить числовые значения, которые затем вы можете использовать в своем запросе.

Вероятно, самый простой способ - использовать простую логику для вычисления среднего или верхнего предела с использованием строковых функций и преобразования строки в числовые функции.

Если все, что вам нужно, это верхний предел, просто получите символы после '-' и используйте это.

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