小编典典

计算一行中为NULL的属性的数量

sql

我想向表中添加一个新列,以记录每个元组(行)的值为空的属性的数量。如何使用SQL来获取号码?

例如,如果一个元组是这样的:

Name | Age | Sex
-----+-----+-----
Blice| 100 | null

我想这样更新元组:

Name | Age | Sex | nNULL
-----+-----+-----+--------
Blice| 100 | null|  1

另外,由于我正在编写PL / pgSQL函数,并且表名是从参数获取的,因此我事先不知道表的架构。这意味着我需要使用输入表名来更新表。有人知道怎么做吗?


阅读 251

收藏
2021-05-23

共1个答案

小编典典

可能 不需要列说明 。将列反向旋转到行并计数。

聚合函数count(<expression>)仅对非空值进行count(*)计数,而对 所有 行进行计数。count(*) - count(col)…为多个列计算NULL值的最快捷方法是…

适用于具有 任何 列数的数据类型的 任何 表。 __any

在具有内置JSON函数的Postgres 9.3+中:

SELECT *, (SELECT count(*) - count(v)
           FROM json_each_text(row_to_json(t)) x(k,v)) AS ct_nulls
FROM   tbl t;

什么x(k,v)

json_each_text()返回一组包含两列的行。默认的列名是keyvalue正如我在链接手册中所见。我提供了表和列别名,因此我们不必依赖默认名称。第二列名为v

或者,在至少8.3起的任何Postgres版本中,
hstore

安装了附加模块,甚至更短,更快一点:

SELECT *,  (SELECT count(*) - count(v) FROM svals(hstore(t)) v) AS ct_nulls
FROM   tbl t;

这个更简单的版本仅返回一组单个值。我仅提供一个简单的别名v,该别名会自动作为表 列的别名。

由于附加列在 功能上依赖的,因此 我将考虑 根本不
将其保留在表中。而不是像上面演示的那样快速地对其进行计算,或者为此目的创建一个具有多态输入类型的小函数:

CREATE OR REPLACE FUNCTION f_ct_nulls(_row anyelement)
  RETURNS int  LANGUAGE sql IMMUTABLE PARALLEL SAFE AS
'SELECT (count(*) - count(v))::int FROM svals(hstore(_row)) v';

PARALLEL SAFE仅适用于Postgres 9.6或更高版本。)

然后:

SELECT *, f_ct_nulls(t) AS ct_nulls
FROM   tbl t;

你可以把它包装成一个VIEW

SQL Fiddle 演示了所有内容。

这也应该回答您的第二个问题:

…表名是从参数获得的,我事先不知道表的架构。这意味着我需要使用输入表名来更新表。

2021-05-23