我想向表中添加一个新列,以记录每个元组(行)的值为空的属性的数量。如何使用SQL来获取号码?
例如,如果一个元组是这样的:
Name | Age | Sex -----+-----+----- Blice| 100 | null
我想这样更新元组:
Name | Age | Sex | nNULL -----+-----+-----+-------- Blice| 100 | null| 1
另外,由于我正在编写PL / pgSQL函数,并且表名是从参数获取的,因此我事先不知道表的架构。这意味着我需要使用输入表名来更新表。有人知道怎么做吗?
可能 不需要列说明 。将列反向旋转到行并计数。
聚合函数count(<expression>)仅对非空值进行count(*)计数,而对 所有 行进行计数。count(*) - count(col)…为多个列计算NULL值的最快捷方法是…
count(<expression>)
count(*)
count(*) - count(col)
适用于具有 任何 列数的数据类型的 任何 表。 __any
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)啊
x(k,v)
json_each_text()返回一组包含两列的行。默认的列名是key,value正如我在链接的手册中所见。我提供了表和列别名,因此我们不必依赖默认名称。第二列名为v。
json_each_text()
key
value
v
或者,在至少8.3起的任何Postgres版本中, hstore 安装了附加模块,甚至更短,更快一点:
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或更高版本。)
PARALLEL SAFE
然后:
SELECT *, f_ct_nulls(t) AS ct_nulls FROM tbl t;
你可以把它包装成一个VIEW…
VIEW
SQL Fiddle 演示了所有内容。
这也应该回答您的第二个问题:
…表名是从参数获得的,我事先不知道表的架构。这意味着我需要使用输入表名来更新表。