我正在使用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
答案 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;