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
  • 相关阅读:
    为什么多线程读写 shared_ptr 要加锁?
    iOS开发那些事iOS6 UI状态保持和恢复
    Hook钩子程序(续)
    JavaScript 项目构建工具 Grunt 实践:任务和指令
    浏览器插件之ActiveX开发(五)
    mongodb副本集架构搭建
    Hadoop 0.23.3版本
    Grails 中使用 grailseventspush 实现 ajax/comet/websocket 消息推送
    razor中@相对于<% %>的优势
    Chrome developer tool介绍(javascript调试)
  • 原文地址:https://www.cnblogs.com/lottu/p/5666706.html
Copyright © 2011-2022 走看看