Как проверить, является ли число NaN

Мне нужно проверить, не является ли числовое/плавающее значение в PostgreSQL числом (NaN). Обратите внимание, что PostgreSQL рассматривает NaN значения как равные. Поскольку я не вижу никакой функции isnan в PostgreSQL 9.3, вот моя лучшая попытка сделать ее:

create or replace function isnan(double precision) returns boolean as
  $$select $1::text = 'NaN'::text$$ language sql;

Есть ли лучший способ проверить NaNs?


person Mike T    schedule 16.09.2014    source источник


Ответы (4)


Есть ли лучший способ проверить NaN?

Просто сравните на равенство:

SELECT double precision 'NaN' = double precision 'NaN';

поскольку, согласно документам, на которые вы ссылаетесь, Pg рассматривает NaNs как равные. Я удивлен этим, учитывая, что он правильно рассматривает NULL как не равный любому другому NULL, и ожидал, что NaN = NaN вернет NULL, но... ну, это работает.

Или, если вам нужна функция:

create or replace function isnan(double precision) 
language sql
immutable
returns boolean as $$
select $1 = double precision 'NaN'
$$;
person Craig Ringer    schedule 16.09.2014
comment
Будучи относительно новым для plpgsql, мне кажется, что, поскольку float == float8 == double precision (по крайней мере, в настоящее время), вы, вероятно, захотите выбрать один синоним и использовать его последовательно. - person David J.; 17.03.2017

Любое значение NaN, взятое со знаком минус, по-прежнему является значением NaN (точно так же, как ноль), поэтому вы можете попробовать следующее:

create or replace function isnan(double precision) returns boolean as $$
select $1 = -$1 and $1 != 0.0 $$ language sql;

or:

create or replace function isnan(double precision) returns boolean as $$
select $1 = -$1 and $1 = $1 + 1.0 $$ language sql;

Поскольку PostgreSQL обрабатывает значения NaN больше, чем все значения, отличные от NaN, возможен следующий трюк:

create or replace function isnan(double precision) returns boolean as $$
select $1 > 0 and -$1 > 0 $$ language sql;
person Podgorskiy    schedule 16.09.2014

Вы также можете использовать приведения типов для создания фактического значения NaN для сравнения:

SELECT *
FROM (VALUES
    (1, 100),
    (2, 'NaN'::NUMERIC),
    (3, 300)
) A
WHERE column2 = 'NaN'::NUMERIC;

Что соответствует только значениям NaN:

column1 | column2
--------+--------
      2 |    NaN
person Malvineous    schedule 19.05.2021

Для Google BigQuery (и, возможно, других серверов sql) используйте следующее

SELECT * FROM [project:dataset.table]
WHERE IS_NAN(field) = true
person jaycode    schedule 02.07.2016
comment
Вопрос про postgresql, где IS_NAN не определен - person Fábio Dias; 13.09.2016