zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    Maximum Flow Exhaustion of Paths Algorithm
    ubuntu下安装java环境
    visualbox使用(二)
    vxworks一个超级奇怪的错误(parse error before `char')
    February 4th, 2018 Week 6th Sunday
    February 3rd, 2018 Week 5th Saturday
    February 2nd, 2018 Week 5th Friday
    February 1st, 2018 Week 5th Thursday
    January 31st, 2018 Week 05th Wednesday
    January 30th, 2018 Week 05th Tuesday
  • 原文地址:https://www.cnblogs.com/lottu/p/5666706.html
Copyright © 2011-2022 走看看