IsNumeric и Case - когда считать числовые значения и изменять способ их отображения в результатах. - PullRequest
0 голосов
/ 21 сентября 2018

Я пытаюсь получить данные из опроса клиентов по телефону.В опросе есть 3 вопроса, а ответы иногда бывают числовыми, а иногда и словами.Я хочу посчитать ответы, но нужно, чтобы любые числовые значения были подсчитаны и отображены как NUMERIC_ENTRY.Я пробовал 'IsNumeric' и 'Case when', но не могу исправить результаты.

Образцы данных:

Question | Answer  
Q1       | 12  
Q1       | 456  
Q1       | 8  
Q1       | DontKnow  
Q1       | TellMeHow  
Q2       | Yes  
Q3       | No

Образец результата:

Question | Asnwer          | Count  
Q1       |  NUMERIC_ENTRY  | 3  
Q1       | DontKnow        | 1  
Q1       | TellMeHow       | 1  
Q2       | Yes             | 1  
Q3       | No              | 1  

Пример SQL:

select Question, Answer, count (*) from Survey
where Client = 'ABC_Company'   
group by Question, Answer

Ответы [ 4 ]

0 голосов
/ 21 сентября 2018

Не используйте isnumeric().Вы будете удивлены некоторыми вещами, считающимися числовыми (например, '$', ',' и '3e2').

Итак, like ваш друг в этом случае.Под numeric я полагаю, вы имеете в виду все цифры.Поскольку вы хотите агрегировать по результатам, вам нужно дважды обратиться к столбцу.Итак, я собираюсь предложить apply:

select s.question, v.answer_group, count(*)
from survey s cross apply
     (values (case when s.answer like '%[^0-9]%' then s.answer  -- has non-digit
                   else 'NUMERIC_ENTRY'
              end)
     ) v(answer_group)
group by s.question, v.answer_group
order by s.question, count(*) desc, v.answer_group;

Обратите внимание, что эта строка обрабатывается как числовая.Это легко настроить;ваш вопрос не ясно, что делать в этом случае.Я мог бы предложить:

     (values (case when ltrim(rtrim(s.answer)) = '' or s.answer is null then 'BLANK_ENTRY'
                   when s.answer like '%[^0-9]%' then s.answer  -- has non-digit
                   else 'NUMERIC_ENTRY'
              end)
     ) v(answer_group)
0 голосов
/ 21 сентября 2018

Вы можете использовать LIKE и шаблон, который соответствует любому нецифровому символу.

SELECT question,
       CASE
         WHEN answer = ''
               OR answer LIKE '%[^0-9]%'
           answer
         ELSE
           'NUMERIC_ENTRY'
       END answer,
       count(*)
       FROM survey
       WHERE client = 'ABC_Company'   
       GROUP BY question,
                CASE
                  WHEN answer = ''
                        OR answer LIKE '%[^0-9]%'
                    answer
                  ELSE
                    'NUMERIC_ENTRY'
                END;

(Предполагается, что SQL Server из-за isnumeric() (который вы также можете использовать, но, как известно,чтобы иногда показывать забавные результаты, я бы предпочел использовать LIKE).)

Другой вариант, поскольку в SQL Server 2012 используется try_cast(), чтобы проверить, можно ли преобразовать строку в целое число.

SELECT question,
       CASE
         WHEN answer = ''
               OR try_cast(answer AS integer) IS NULL
           answer
         ELSE
           'NUMERIC_ENTRY'
       END answer,
       count(*)
       FROM survey
       WHERE client = 'ABC_Company'   
       GROUP BY question,
                CASE
                  WHEN answer = ''
                        OR try_cast(answer AS integer) IS NULL
                    answer
                  ELSE
                    'NUMERIC_ENTRY'
                END;
0 голосов
/ 21 сентября 2018

Для MySQL: Исходя из https://stackoverflow.com/a/5065007/2469308,, вы можете проверить, является ли строка числовой или нет, используя функцию If () .

Попробуйте следующий запрос:

select Question, 
       IF(CONCAT('',Answer * 1) = Answer, 'NUMERIC_ENTRY', Answer) AS Ans, 
       COUNT(*)
FROM Survey
where Client = 'ABC_Company'   
GROUP BY Question, Ans 
0 голосов
/ 21 сентября 2018

Используйте функцию TRY_PARSE при условии, что ваша версия SQL Server 2012 или выше ( @ Гордон прав, используя функцию ISNUMERIC, может быть проблематично, как в приведенной ниже демонстрационной ссылке ):

select q.Question, q.AnswerCount, count(q.AnswerCount) as count
  from
(
select Question, 
       (case when TRY_PARSE(Answer as int) is not null then 'NUMERIC_ENTRY'
            else Answer end) as AnswerCount
  from Survey   
 where Client = 'ABC_Company'   
 group by Question, Answer
) as q
group by q.Question, q.AnswerCount
order by q.Question, count desc

Rextester Demo

...