• oracle VS postgresql系列-行列转换


    【需求】例如先有数据为
     id  |  name   
    ------+---------
     1001 | lottu
     1001 | xuan
     1001 | rax
     1002 | ak
     1002 | vincent
    现在需要转换为
      id  |     names      
    ------+----------------
     1001 | lottu|xuan|rax
     1002 | ak|vincent
    反之;oracle,postgresql有如何对待
    【列转行】
    oracle 
    对oracle;看到这样的需求;立刻想到vm_concat,listagg函数;这样sql就出来了
    select id, vm_concat(name,'|')as names from lottu01 group by id;
    
    select id, listagg(name,'|') within group(order by null) as names from lottu01 group by id;
     postgresql
    同理也有对应的函数string_agg
    mydb=> select id,string_agg(name,'|') from lottu01 group by id;
      id  |   string_agg   
    ------+----------------
     1002 | ak|vincent
     1001 | lottu|xuan|rax
    【行转列】
    oracle
      这个一看就要使用分割函数;对oracle目前是不存在split函数
    分割函数这个可以查考--http://www.cnblogs.com/lottu/p/4013751.html
    当然我们可以用其他函数来替代 正则函数 regexp_substr
    select id,regexp_substr(names,'[^|]+',1,level) as name from lottu02
    connect by id = prior id
    and prior dbms_random.value is not null
    and level <= length(regexp_replace(names, '[^|]'))+1;
    #或者
    select id,regexp_substr(names,'[^|]+',1,level) as name from lottu02
    connect by id = prior id
    and prior dbms_random.value is not null
    and level <= regexp_count(names, '|')+1;
    postgresql
     postgresql里面有分割函数--split_part;还是不能按照上面的写法来改;因为目前的postgresql不支持 connect by语法;
    不过没关系;这并不妨碍写法不能实现。
    另外 postgresql针对这个有个正则函数--regexp_split_to_table;可以直接实现。
    --借用with recursive的语法来替换 connect by的写法。
    mydb=> with recursive t(id,lv) as(
    mydb(> select id,1 lv from lottu02
    mydb(> union all
    mydb(> select ts.id, t.lv+1 from t, lottu02 ts where t.id = ts.id and t.lv < length(ts.names)-length(replace(ts.names,'|','')) + 1
    mydb(> )
    mydb-> select t1.id,split_part(t1.names,'|',t2.lv) from lottu02 t1,t t2
    mydb-> where t1.id = t2.id; 
      id  | split_part 
    ------+------------
     1001 | lottu
     1001 | xuan
     1001 | rax
     1002 | ak
     1002 | vincent
    
    -- 借用regexp_split_to_table轻松实现。
    mydb=> select id,regexp_split_to_table(names,'|') from lottu02;
      id  | regexp_split_to_table 
    ------+-----------------------
     1001 | lottu
     1001 | xuan
     1001 | rax
     1002 | ak
     1002 | vincen
  • 相关阅读:
    Git Bash 下操作文件及文件夹命令
    python django -2 ORM模型
    python django -1
    redis python交互和实际例子
    MongoDB API和python操作
    python mysql 封装
    fabric 自动化部署
    linux 开机自启
    linux shell习题训练
    linux grep sed awk
  • 原文地址:https://www.cnblogs.com/lottu/p/5666706.html
Copyright © 2020-2023  润新知