Приведение к int вместо десятичного? - PullRequest
0 голосов
/ 06 мая 2019

У меня есть поле, содержащее до 9 значений, разделенных запятыми, каждое из которых имеет строковое значение и числовое значение, разделенное двоеточием.После анализа их всех некоторые значения между 0 и 1 устанавливаются как целое число, а не как числовое значение.Проблема, очевидно, связана с типом данных, но я не уверен, что вызывает это или как это исправить.Проблема существует только в операторе case, кажется, что функция split_part работает идеально.

То, что я пробовал:

  1. nvl(split_part(one,':',2),0) = COALESCE типы текста и целого числаневозможно сопоставить

  2. nvl(split_part(one,':',2)::numeric,0) => Неверный синтаксис ввода для числового типа

  3. многочисленные другие варианты преобразования / преобразования

  4. (CASE WHEN split_part(one,':',2) = '' THEN 0::numeric ELSE split_part(one,':',2)::numeric END)::numeric => работает, но получает значение int 0

При использовании функции split_part вне оператора case она работает правильно.Однако мне нужно, чтобы результат был нулевым для нулевых значений.

split_part(one,':',2) => 0.02068278096187390979 (ожидаемый результат)

При выполнении кода выше я получаю ноль, но ожидаю 0.02068278096187390979

Поле «one» имеет следующее значение «xyz: 0.02068278096187390979» перед функцией split_part.

ПРИМЕР:

create table test(one varchar); 

insert into test values('XYZ: 0.50000000000000000000') 

select
  one ,split_part(one,':',2) as correct_value_for_those_that_are_not_null ,
  case 
    when split_part(one,':',2) = '' then null 
    else split_part(one,':',2)::numeric 
  end::numeric as this_one_is_the_problem
from test

1 Ответ

0 голосов
/ 07 мая 2019

Однако мне нужно, чтобы результат был нулевым для нулевых значений.

Ваш пример не имеет значения NULL вообще. Только адресация пустой строки ('').
Надежно, эффективно и без проблем заменить либо на 0:

SELECT part1, CASE WHEN part2 <> '' THEN part2::numeric ELSE numeric '0' END AS part2
FROM (
   SELECT split_part(one, ':', 1) AS part1
        , split_part(one, ':', 2) AS part2
   FROM   test
   ) sub;

См:

Также обратите внимание, что все ветви SQL CASE должны согласовывать общий тип данных. В прошлом были незначительные корректировки в логике, которая определяет результирующий тип, поэтому версия Postgres может сыграть свою роль в угловых случаях. Не вспоминайте детали сейчас.

nvl() не является функцией Postgres. Вы, вероятно, имели в виду COALESCE. Руководство:

Эта стандартная функция SQL предоставляет возможности, аналогичные NVL и IFNULL, которые используются в некоторых других системах баз данных.

...