计算行

时间:2016-01-22 00:17:27

标签: regex postgresql function null plpgsql

我正在尝试确定填充的特定列的数量,这是我正在尝试做的事情:

  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似乎不起作用。我对任何其他找到非零列数的方法持开放态度。

4 个答案:

答案 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

SQL小提琴:http://sqlfiddle.com/#!15/2ab3c/7/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 ║
╚═════╩═════════╩═════════╩═════════╩═════════════╝