如何在pgsql中计算值大于0的逗号分割值?

时间:2016-11-03 15:09:19

标签: sql postgresql postgresql-8.4

我正在使用PostgreSQL并将数据库中的值存储为逗号分割。现在我想计算所有逗号分裂值,其中单个值大于零

我怎样才能实现它?

我的db列值看起来像

0,120,0,0,118,0,0,128,0,123,0,0,0,125,0
192,193,196,195
192,193,196,1950,128,0,123,0,0,

我尝试的是:

SELECT case when col='0' then 0 else array_length(regexp_split_to_array(replace(replace(col,'0,',''),',0',''), ','), 1) end 
FROM table

这里的问题是它取代所有0,即使它存在于任何其他值

注意:我正在使用 PostgreSQL 8.4.2

2 个答案:

答案 0 :(得分:1)

这是一个糟糕的数据库设计。但是,这是一种使用length()的方法:

select (length(replace('[' || replace(col, ',', '][') || ']', '[0]', '')) -
        length(replace(replace('[' || replace(col, ',', '][') || ']', '[0]', ''), '[', '')) 
       )

在这种情况下,replace()很简洁,只有逗号。以下是代码工作的示例:

select replace('[' || replace(col, ',', '][') || ']', '[0]', ''),
       (length(replace('[' || replace(col, ',', '][') || ']', '[0]', '')) -
        length(replace(replace('[' || replace(col, ',', '][') || ']', '[0]', ''), '[', '')) 
       )
 from (select 'a,0,0,b'::text as col union all
       select '1,2,3,0,0,0,1,1,0,0,1'::text) x

答案 1 :(得分:1)

您需要取消()数组中的值(实质上将其转换为正确规范化的模型),然后您可以正确计算它们:

我不清楚你是否要计算表中所有行或每行的非零值。

在所有行中计算:

select count(*)
from the_table, 
     unnest(string_to_array(the_column, ',')) as x(v) 
where v::int > 0;

如果您需要为每一行计算它们,您可以这样做,假设您在表中有一个主键(或唯一)列:

select id, count(*)
from the_table, 
     unnest(string_to_array(the_column, ',')) as x(v) 
where v::int > 0
group by id;

以上假设列id是唯一的。

修改

对于旧的和不受支持的Postgres版本,您需要将其更改为:

select count(*)
from (
  select unnest(string_to_array(the_column, ',')) v
  from the_table
) t  
where v::int > 0

select id, count(*)
from (
  select id, unnest(string_to_array(the_column, ',')) v
  from the_table
) t
where v::int > 0
group by id;