2017-07-24 35 views
0

如何更新/替换逗号分隔字符串列上的值?如何更新postgresql中逗号分隔字符串的值

即:

121720 | 121716 | false,true,34,1,1,true,1,true 
118220 | 118191 | false,true,731,11,11,true,11,true 
142125 | 142037 | false,true,34,28,28,true,28,true 
182105 | 182012 | false,true,34,3,3,true,3,true,, 
185268 | 185191 | false,true,34,2,2,true,2,true,, 

如何更换只是字符串(真)的(假)的第二个值? 如果我想用不同的“位置”(如第六或第八位)替换它,该怎么办?

我已经能够使用SELECT上的split_part功能,但不能在UPDATE上使用。

+1

您当前的表格设计是最坏的。即使有人给你提问,他也会成为坏设计的推动者。相反,将每个CSV值移至单独的行。 –

+0

蒂姆是对的。而不是找到一种方法来做到这一点,你应该修复你的数据模型。 –

+0

我不能同意更多@TimBiegeleisen这不是一个漂亮的设计,但它不会在不久的将来改变,尽可能多的,所以我仍然有这种情况下解决。但是,谢谢你的建议。 – p00d33m

回答

0

正如上面评论中提到的,你应该认真考虑改变你的餐桌设计。下面是一个查询其第二CSV值取代了truefalse

update your_table 
set col = regexp_replace(col, '(.*?),true,(.*)', '\1,false,\2') 

该查询的问题,如果它的工作原理是,你将可能需要另一个正则表达式为其它列。如果您添加或删除CSV列,您所写的所有正则表达式可能会中断或失效。

+0

非常感谢@timbiegeleisen。唯一我注意到的是,我必须删除'g',否则下一个真实也将被替换。 – p00d33m

+0

(删除'g')处理后续替换。但是,即使在改变\ 2为所需的位置,例如6或8之后,我仍然无法使其“计数”间隔/位置。当我开始“玩”时,我并不完全控制结果更新......尚未。但是,谢谢,这对我很有帮助。 – p00d33m

+0

如前所述,您需要为其他职位使用不同的正则表达式。真的,你应该投入时间来修复你的数据模型,而不是走这条路。 –

0

你真的需要regexpres吗?

如何创建一个这样的功能?

CREATE OR REPLACE FUNCTION csvupdate(csv text, target_upd text) 
    RETURNS text AS 
$BODY$ 
declare 
a text[]; 
r record; 
begin 
a := string_to_array($1,','); 

FOR r IN select (string_to_array(zz,':')) [1] ::integer id , (string_to_array(zz,':'))[2] ::text val from ( select unnest(string_to_array($2,',')) zz )q1 
loop 
a[r.id] := r.val; 
end loop; 

return array_to_string(a,','); 
end; 
$BODY$ 
    LANGUAGE plpgsql IMMUTABLE 
    COST 100; 

select csvupdate('true,false,1,3,4,false','1:false,4:33') 
+0

感谢您的建议@longbeard_boldy,但以前的答案解决了这个问题,我还没有测试过您的解决方案(尚未)。原来,这个任务比较简单,因为我可以在最后把字符串中的所有“真”更新为“假”。 – p00d33m