我正在尝试确定填充的特定列的数量,这是我正在尝试做的事情:
foo := COALESCE($1.col1, '') || ' ' ||
COALESCE($1.col2, '') || ' ' ||
COALESCE($1.col3, '') || ' ' ||
COALESCE($1.col4, '');
foo := REPLACE(foo, var, ' ');
words := string_to_array(foo, ' ');
RETURN array_length(words, 1);
其中var
是空格,\s
似乎不起作用。我对任何其他找到非零列数的方法持开放态度。
答案 0 :(得分:1)
这样的东西会起作用,而且更容易。
create table foo (
id integer primary key,
col1 text,
col2 text,
col3 text);
insert into foo values
(0, null, null, null),
(1, null, null, 'aa'),
(2, null, 'aa', 'bb'),
(3, 'aa', 'bb', 'cc');
select id,
case when col1 is null then 1 else 0 end +
case when col2 is null then 1 else 0 end +
case when col3 is null then 1 else 0 end as null_columns
from foo;
可生产
0 3
1 2
2 1
3 0
答案 1 :(得分:1)
您可以在Postgres 9.3 或更高版本中使用JSON functions拼写出所有列 - 甚至不知道相关内容时执行此操作:
SELECT t.*, count(value)::int AS notnull_ct -- cast to int is optional
FROM tbl t, json_each_text(row_to_json(t)) -- implicit LATERAL join
-- WHERE key LIKE 'col%' -- optionally consider only selected columns
GROUP BY tbl_id; -- PK column
默认情况下, json_each_text()
会返回(key, value)
。在命名冲突的情况下使用不同的别名和/或表限定名称。如果您只对选定的列感兴趣,则可以在WHERE
子句中过滤列名称。
或者使用附加模块hstore用于相同目的,至少可以使用Postgres 8.3 :
SELECT t.*, count(v)::int AS notnull_ct
FROM tbl t, svals(hstore(t)) v
GROUP BY tbl_id;
主要特征是count()
不计算NULL值(并且永远不会返回NULL)。正是你需要的。
您可以将其封装在一个函数中。具有多态输入类型的简单SQL函数可以完成工作:
CREATE OR REPLACE FUNCTION f_count_notnull_in_row(ANYELEMENT)
RETURNS int LANGUAGE sql IMMUTABLE AS
'SELECT count(value)::int
FROM json_each_text(row_to_json($1))';
呼叫:
SELECT *, f_count_notnull_in_row(t)
FROM tbl t;
SQL Fiddle(重用Bill的设置)。
答案 2 :(得分:0)
以下表为例
| id | col1 | col2 | col3 |
|----|--------|--------|--------|
| 0 | (null) | (null) | (null) |
| 1 | (null) | (null) | aa |
| 2 | (null) | aa | bb |
| 3 | aa | bb | cc |
使用unnest()和array()来获得所需的输出。
SELECT id,count(col) not_null_col_cnt
FROM (SELECT id,unnest(array [col1,col2,col3]) col
FROM foo
) t
GROUP BY id
ORDER BY id
结果:
| id | not_null_col_cnt |
|----|------------------|
| 0 | 0 |
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
答案 3 :(得分:0)
你可以使用简单的演员:
SELECT id,
(col1 IS NULL)::int + (col2 IS NULL)::int + (col3 IS NULL)::int As null_number
FROM table_name;
的 SqlFiddleDemo
强>
输出:
╔═════╦═════════╦═════════╦═════════╦═════════════╗
║ id ║ col1 ║ col2 ║ col3 ║ null_number ║
╠═════╬═════════╬═════════╬═════════╬═════════════╣
║ 1 ║ a ║ b ║ c ║ 0 ║
║ 2 ║ a ║ b ║ (null) ║ 1 ║
║ 3 ║ a ║ (null) ║ (null) ║ 2 ║
║ 4 ║ (null) ║ (null) ║ (null) ║ 3 ║
╚═════╩═════════╩═════════╩═════════╩═════════════╝