Поиск значений (например, NaN) в таблице по всем колонкам сразу
Коллеги, я видел похожие вопросы, но, думаю, вдруг что-то изменилось за те годы, которые прошли с тех пор, как они были заданы.
Есть таблица(-ы) со многими полями. Таблица может быть одна или их может быть много и мы можем их объединить по какому-то уникальному полю. Изначально задача была получить записи не содержащие NaN ни в одном из полей, но, на самом деле, вопрос шире - вместо NaN может быть любое значение.
То есть, если я ищу по одному полю, то, очевидно:
SELECT * FROM table_name
WHERE field_name != 'NaN'::NUMERIC;
Если я ищу по всем полям, то мне надо так или иначе явно указывать названия полей и таблиц. А вот нет чего-то такого:
SELECT * FROM table_name
WHERE table_name.* != 'NaN'::NUMERIC;
(Я знаю - это не работает)
То есть, либо перечислять названия полей вручную, либо с помощью скрипта получать названия и генерировать динамически, либо какие-то очень витиеватые (на мой взгляд) динамические запросы. Во всех этих случаях мне проще затащить все таблицы в pandas и легко и приятно избавится от NaN. Но вдруг можно легко и приятно, но через SQL?
Спасибо!
Ответы (1 шт):
Пример:
create table test (val1 int,val2 int);
insert into test values
(1,2)
,(3,null)
,(null,4)
,(null,null)
;
Запрос
select *
-- строки содержащие только null
,case when t.* is null then 1 else 0 end fIsNull
-- строки не содержащие null
,case when t.* is not null then 1 else 0 end fIsNotNull
-- строки содержащие не null значения
,case when not (t.* is null) then 1 else 0 end fIsNotIsNull
-- строки содержащие null значения
,case when not (t.* is not null) then 1 else 0 end fIsNotIsNotNull
from test t
Результат
| val1 | val2 | fIsNull | fIsNotNull | fIsNotIsNull | fIsNotIsNotNull |
|---|---|---|---|---|---|
| 1 | 2 | 0 | 1 | 1 | 0 |
| 3 | null | 0 | 0 | 1 | 1 |
| null | 4 | 0 | 0 | 1 | 1 |
| null | null | 1 | 0 | 0 | 1 |
Для любопытства, с такими данными
insert into test values
(1,2)
,(3,null)
,(null,4)
,(null,null)
,('NaN'::numeric,null)
,('NaN'::numeric,2)
;
запрос
select *
,concat(t.*) ts
from test t
-- where strpos(concat(t.*),'NaN')=0
выдаст результат
| val1 | val2 | ts |
|---|---|---|
| 1 | 2 | (1,2) |
| 3 | null | (3,) |
| null | 4 | (,4) |
| null | null | (,) |
| NaN | null | (NaN,) |
| NaN | 2 | (NaN,2) |
select *
from test t
where t.* is not null and strpos(concat(t.*),'NaN')=0
| val1 | val2 |
|---|---|
| 1 | 2 |