• 售前

  • 售后

热门帖子
入门百科

PostgreSQL 字符串拆分与归并案例

[复制链接]
雷JY 显示全部楼层 发表于 2021-10-26 13:37:52 |阅读模式 打印 上一主题 下一主题
我就废话不多说了,大家还是直接看代码吧~
  1. with person_name as (
  2.   select c.id,
  3.       array_to_string(array_agg(distinct p.c_name), ' , ') as p_name
  4.   from biz_notification_config c
  5.        join biz_notification_person p
  6.          on p.id =
  7.            any (string_to_array(c.persons, ',')::int[])
  8.   group by c.id
  9. ),
  10.    group_name as (
  11.      select c.id,
  12.         array_to_string(array_agg(distinct g.c_name), ' , ') as g_name
  13.      from biz_notification_config c
  14.          join biz_notification_group g
  15.             on g.id = any (string_to_array(c.c_groups, ',')::int[])
  16.      group by c.id
  17.    )
  18. select config.*, person_name.p_name, group_name.g_name
  19. from biz_notification_config config
  20.      left join person_name
  21.           on config.id = person_name.id
  22.      left join group_name
  23.           on config.id = group_name.id;
复制代码
  1. array_to_string(array_agg(distinct g.c_name), ' , ')
复制代码
:将数组转换为字符串,用“,”分隔。(有点类似于Mysql的group_concat()函数)。
  1. array_agg(distinct 想要合并的数据)
复制代码
:将想要的数据变成数组。
  1. string_to_array(c.c_groups, ‘,')
复制代码
:将字符串按照“,”分隔成数组。
  1. any (String(varchar)::int[])
复制代码
:将字符串转换为整形。
  1. id = any(List)
复制代码
:id的值存在于List中,注意List要和id为同种范例。
增补:POSTGRESQL 与MYSQL 实现分割字符串的方法对比
实现分割字符串。
MYSQL版本。 由于MYSQL不支持递归,不支持返回表范例的结果,以是代码比力繁琐。 我用了两个函数以及一个存储过程来实现。
-- 得到分割符的总数。
  1. DELIMITER $$
  2. CREATE DEFINER=`root`@`%` FUNCTION `func_get_split_string_total`(
  3. f_string VARCHAR(1000),f_delimiter VARCHAR(5)
  4. ) RETURNS INT(11)
  5. BEGIN
  6. -- Get the total number of given string.
  7. RETURN 1+(LENGTH(f_string) - LENGTH(REPLACE(f_string,f_delimiter,'')));
  8. END$$
  9. DELIMITER ;
复制代码
-- 得到详细下表的子字符。
  1. DELIMITER $$
  2. CREATE DEFINER=`root`@`%` FUNCTION `func_get_split_string`(
  3. f_string VARCHAR(1000),f_delimiter VARCHAR(5),f_order INT) RETURNS VARCHAR(255) CHARSET utf8
  4. BEGIN
  5. -- Get the separated number of given string.
  6. DECLARE result VARCHAR(255) DEFAULT '';
  7. SET result = REVERSE(SUBSTRING_INDEX(REVERSE(SUBSTRING_INDEX(f_string,f_delimiter,f_order)),f_delimiter,1));
  8. RETURN result;
  9. END$$
  10. DELIMITER ;
复制代码
-- 打印结果。 用临时表来实现。
  1. DELIMITER $$
  2. CREATE PROCEDURE `sp_print_result`(
  3. IN f_string VARCHAR(1000),IN f_delimiter VARCHAR(5)
  4. )
  5. BEGIN
  6. -- Get the separated string.
  7. DECLARE cnt INT DEFAULT 0;
  8. DECLARE i INT DEFAULT 0;
  9. SET cnt = func_get_split_string_total(f_string,f_delimiter);
  10. DROP TABLE IF EXISTS tmp_print;
  11. CREATE TEMPORARY TABLE tmp_print (v_text varchar(200) NOT NULL);
  12. WHILE i < cnt
  13. DO
  14.   SET i = i + 1;
  15.   INSERT INTO tmp_print(v_text) VALUES (func_get_split_string(f_string,f_delimiter,i));
  16. END WHILE;
  17. SELECT * FROM tmp_print;
  18. END$$
  19. DELIMITER ;
复制代码
我们来实验:
  1. CALL sp_print_result('love,you,hate,number',',');
  2. query result
  3. v_text
  4. love
  5. you
  6. hate
  7. number
复制代码
PostgreSQL比力机动, 有以下几种方法来实现。
第一种,平凡的分析字符串方法。
  1. create or replace function split_to_string(
  2. IN f_string text,
  3. IN f_delimiter varchar(10)
  4. ) returns setof text as
  5. $ytt$
  6. declare cnt int;
  7. declare i int;
  8. declare v_result text;
  9. begin
  10.    i := 1;
  11.    cnt := length(f_string) - length(replace(f_string,f_delimiter,''))+1;
  12.    while i <= cnt
  13.    loop
  14.     v_result := split_part(f_string,f_delimiter,i);
  15. return next v_result;
  16.     i := i + 1;
  17.    end loop;
  18. end;
  19. $ytt$ language plpgsql;
复制代码
结果:
  1. t_girl=# select split_to_string('love,you,hate,number',',') as result;
  2. result
  3. --------
  4. love
  5. you
  6. hate
  7. number
  8. (4 rows)
复制代码
第二种, 用自己带的正则函数来实现。
  1. t_girl=# SELECT ytt FROM regexp_split_to_table('love,you,hate,number', E',+') AS ytt;
  2. ytt  
  3. --------
  4. love
  5. you
  6. hate
  7. number
  8. (4 rows)
  9. t_girl=#
复制代码
第三种,用自带的WITH 语法来实现。
  1. t_girl=# with recursive ytt(f1,f2) as (
  2. values (0,' '::text)
  3. union all
  4. select f1+1,split_part('love,you,hate,number',',',f1+1) from ytt where f1 < 20
  5. )
  6. select f2 as result from ytt where f1 >=1 and f1 <= length('love,you,hate,number')-length(replace('love,you,hate,number',',',''))+1;
  7. result
  8. --------
  9. love
  10. you
  11. hate
  12. number
  13. (4 rows)
  14. Time: 0.742 ms
复制代码
以上为个人经验,希望能给大家一个参考,也希望大家多多支持草根技术分享。如有错误或未思量完全的地方,望不吝见教。

帖子地址: 

回复

使用道具 举报

分享
推广
火星云矿 | 预约S19Pro,享500抵1000!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

草根技术分享(草根吧)是全球知名中文IT技术交流平台,创建于2021年,包含原创博客、精品问答、职业培训、技术社区、资源下载等产品服务,提供原创、优质、完整内容的专业IT技术开发社区。
  • 官方手机版

  • 微信公众号

  • 商务合作