PostgreSQL 字符串拆分与合并案例
我就废话不多说了,大家还是直接看代码吧~
withperson_nameas( selectc.id, array_to_string(array_agg(distinctp.c_name),',')asp_name frombiz_notification_configc joinbiz_notification_personp onp.id= any(string_to_array(c.persons,',')::int[]) groupbyc.id ), group_nameas( selectc.id, array_to_string(array_agg(distinctg.c_name),',')asg_name frombiz_notification_configc joinbiz_notification_groupg ong.id=any(string_to_array(c.c_groups,',')::int[]) groupbyc.id ) selectconfig.*,person_name.p_name,group_name.g_name frombiz_notification_configconfig leftjoinperson_name onconfig.id=person_name.id leftjoingroup_name onconfig.id=group_name.id;
array_to_string(array_agg(distinctg.c_name),','):将数组转换为字符串,用“,”分隔。(有点类似于Mysql的group_concat()函数)。
array_agg(distinct想要合并的数据):将想要的数据变成数组。
string_to_array(c.c_groups,‘,'):将字符串按照“,”分隔成数组。
any(String(varchar)::int[]):将字符串转换为整形。
id=any(List):id的值存在于List中,注意List要和id为同种类型。
补充:POSTGRESQL与MYSQL实现分割字符串的方法对比
实现分割字符串。
MYSQL版本。由于MYSQL不支持递归,不支持返回表类型的结果,所以代码比较繁琐。我用了两个函数以及一个存储过程来实现。
--得到分割符的总数。
DELIMITER$$ CREATEDEFINER=`root`@`%`FUNCTION`func_get_split_string_total`( f_stringVARCHAR(1000),f_delimiterVARCHAR(5) )RETURNSINT(11) BEGIN --Getthetotalnumberofgivenstring. RETURN1+(LENGTH(f_string)-LENGTH(REPLACE(f_string,f_delimiter,''))); END$$ DELIMITER;
--得到具体下表的子字符。
DELIMITER$$ CREATEDEFINER=`root`@`%`FUNCTION`func_get_split_string`( f_stringVARCHAR(1000),f_delimiterVARCHAR(5),f_orderINT)RETURNSVARCHAR(255)CHARSETutf8 BEGIN --Gettheseparatednumberofgivenstring. DECLAREresultVARCHAR(255)DEFAULT''; SETresult=REVERSE(SUBSTRING_INDEX(REVERSE(SUBSTRING_INDEX(f_string,f_delimiter,f_order)),f_delimiter,1)); RETURNresult; END$$ DELIMITER;
--打印结果。用临时表来实现。
DELIMITER$$ CREATEPROCEDURE`sp_print_result`( INf_stringVARCHAR(1000),INf_delimiterVARCHAR(5) ) BEGIN --Gettheseparatedstring. DECLAREcntINTDEFAULT0; DECLAREiINTDEFAULT0; SETcnt=func_get_split_string_total(f_string,f_delimiter); DROPTABLEIFEXISTStmp_print; CREATETEMPORARYTABLEtmp_print(v_textvarchar(200)NOTNULL); WHILEi我们来执行:
CALLsp_print_result('love,you,hate,number',','); queryresult v_text love you hate numberPostgreSQL比较灵活,有以下几种方法来实现。
第一种,普通的分析字符串方法。
createorreplacefunctionsplit_to_string( INf_stringtext, INf_delimitervarchar(10) )returnssetoftextas $ytt$ declarecntint; declareiint; declarev_resulttext; begin i:=1; cnt:=length(f_string)-length(replace(f_string,f_delimiter,''))+1; whilei<=cnt loop v_result:=split_part(f_string,f_delimiter,i); returnnextv_result; i:=i+1; endloop; end; $ytt$languageplpgsql;结果:
t_girl=#selectsplit_to_string('love,you,hate,number',',')asresult; result -------- love you hate number (4rows)第二种,用自己带的正则函数来实现。
t_girl=#SELECTyttFROMregexp_split_to_table('love,you,hate,number',E',+')ASytt; ytt -------- love you hate number (4rows) t_girl=#第三种,用自带的WITH语法来实现。
t_girl=#withrecursiveytt(f1,f2)as( values(0,''::text) unionall selectf1+1,split_part('love,you,hate,number',',',f1+1)fromyttwheref1<20 ) selectf2asresultfromyttwheref1>=1andf1<=length('love,you,hate,number')-length(replace('love,you,hate,number',',',''))+1; result -------- love you hate number (4rows) Time:0.742ms以上为个人经验,希望能给大家一个参考,也希望大家多多支持毛票票。如有错误或未考虑完全的地方,望不吝赐教。