Oralce 按分隔符把一列转成多行
1.前言
最近因项目需求,需要把员工的工作组返回给前台,但是数据库是把员工的工作组Id,都存在一个字段内了(以“逗号”分隔),而这样不符合前台的需要,他们需要一行,一行的数据。如:
数据库:
userId, workgroup
,,
,,
前台需要:
userId, workgroup
2. 分析思路:
大体的思路是这样的:
首先:要知道,每一员工最多有多少个组。
其次:建一个有关“数”的临时表,与上面的组数进行关联,这样就出现了“多”行
最后:多“行”有了,剩下的就是对每一行的组进行刷选。如第一行取第一个逗号左边的,第二行取第二个逗号左边的, 依此类推。
3. 实现:
根据上次的思路,来实现:
第一步:
with v_usergroups as (select '' as userId,'10,12,15' as workgroups from dual
union
select '' as userId,'2,4,5' as workgroups from dual
)
select userid,',' || workgroups ||',' AS tempgroups,length(workgroups || ',') - nvl(length(REPLACE(workgroups, ',')), 0) AS groupcount FROM v_usergroups
PS: 这里在"workgroup" 的前后也加了逗号,是为了后面使用方面。
第二步:
select LEVEL lv from dual CONNECT BY LEVEL <= 5
PS:这里的5,我们是根据业务需要,每一员工最多分为5个组,当然也可以写其他的值,但一定要大于第一步求得的"groupcount".
到这里后,我们对这两个表进行关联,看看值怎么样:
with v_usergroups as (select '' as userId,'10,12,15' as workgroups from dual
union
select '' as userId,'2,4,5' as workgroups from dual
)
select * from
(select userid,',' || workgroups ||',' AS tempgroups,length(workgroups || ',') - nvl(length(REPLACE(workgroups, ',')), 0) AS groupcount FROM v_usergroups ) a,
(select LEVEL lv from dual CONNECT BY LEVEL <= 5) b where b.lv<=a.groupcount
order by userid,lv
USERID TEMPGROUPS GROUPCOUNT LV
1 1001 ,10,12,15, 3 1
2 1001 ,10,12,15, 3 2
3 1001 ,10,12,15, 3 3
4 1002 ,2,4,5, 3 1
5 1002 ,2,4,5, 3 2
6 1002 ,2,4,5, 3 3
到这里,就离我们最终的结果很近了。 只需要在外层对"tempgroups"做一下简单的处理就可以了:
第三步:
这一步的主要思路就是:截串。第一个组应该是第一逗号和第二个逗号之间的值,第二个组应该是第二个逗号与第三个逗号之间的值,那第一个,和第二个如何表示呢,其实就是利用字段lv。也就是:
substr(tempgroups,instr(tempgroups, ',', 1, lv) + 1,instr(tempgroups, ',', 1, lv + 1) - (instr(tempgroups, ',', 1, lv) + 1))
最后的SQL 如下:
with v_usergroups as (select '' as userId,'10,12,15' as workgroups from dual
union
select '' as userId,'2,4,5' as workgroups from dual
)
select userid,substr(tempgroups,instr(tempgroups, ',', 1, lv) + 1,instr(tempgroups, ',', 1, lv + 1) - (instr(tempgroups, ',', 1, lv) + 1)) from
(select userid,',' || workgroups ||',' AS tempgroups,length(workgroups || ',') - nvl(length(REPLACE(workgroups, ',')), 0) AS groupcount FROM v_usergroups ) a,
(select LEVEL lv from dual CONNECT BY LEVEL <= 5) b where b.lv<=a.groupcount
order by userid,lv
Oralce 按分隔符把一列转成多行的更多相关文章
- SQL Server 行转列,列转行。多行转成一列
一.多行转成一列(并以","隔开) 表名:A 表数据: 想要的查询结果: 查询语句: SELECT name , value = ( STUFF(( SELECT ',' + va ...
- SQL查询结果列拼接成逗号分隔的字符串:group_concat
转自:SQL查询结果列拼接成逗号分隔的字符串 背景:做SQL查询时会经常需要,把查询的结果拼接成一个字符串. 解决方法: 通过 group_concat 函数 拼接的结果很长,导致拼接结果显示不全,可 ...
- C#将datatable的某一列转换成json格式的字符串
将datatable的某一列转换成json格式的字符串(转换完后自己在字符串前后加{}) /// <summary> ///DataTable装换 Column数据 组合成json 现在的 ...
- 将excel按照某一列拆分成多个文件(方案整理)
1解决方案:将excel按照某一列拆分成多个文件 https://blog.csdn.net/ntotl/article/details/79141314 2遇到的问题:解决vbe6ext.olb不能 ...
- 学习excel的使用技巧复制一列文本成新列去重
学习excel的使用技巧复制一列文本成新列去重 其实比较简单的技巧 知道了就会 不知道就比较麻烦 直接复制到一列 找到 数据选项 删除重复项
- 利用泛型和反射,管理配置文件,把Model转换成数据行,并把数据行转换成Model
利用泛型和反射,管理配置文件,把Model转换成数据行,并把数据行转换成Model 使用场景:网站配置项目,为了便于管理,网站有几个Model类来管理配置文件, 比如ConfigWebsiteMo ...
- 【Azure 环境】Azure Resource Graph Explorer 中实现动态数组数据转换成多行记录模式 - mv-expand
问题描述 想对Azure中全部VM的NSG资源进行收集,如果只是查看一个VM的NSG设定,可以在门户页面中查看表格模式,但是如果想把导出成表格,可以在Azure Resource Graph Expl ...
- DataGridView列的宽度、行的高度自动调整
注意:DataGridView控件是从.NET Framework 2.0版本开始追加的. 介绍一下DataGridView列的宽度和行的高度,根据单元格或Header的内容(一般是内容全部被表示)自 ...
- 转:DataGridView列的宽度、行的高度自动调整
注意:DataGridView控件是从.NET Framework 2.0版本开始追加的. 介绍一下DataGridView列的宽度和行的高度,根据单元格或Header的内容(一般是内容全部被表示)自 ...
随机推荐
- AngularJs练习Demo12Provider
@{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport&quo ...
- silverlight visifire控件图表制作——silverlight 后台方法打印
一.后台方法 1.添加引用:using System.Windows.Printing; 2.全局变量://定义图片和文本打印变量 PrintDocument printImage; 3.构造方法体 ...
- 抽空通过简书网学习了一下console,感觉高大上!
抽空看了一下简书中关于console的文章,为了便于自己今后查看,自己写了一遍!原文地址:http://www.jianshu.com/p/f961e1a03a56 测试代码在最下面 1.consol ...
- vs UNICODE 零散的笔记
string--->CString #ifdef UNICODE#define Tstring wstring#else#define Tstring string#endif 可以这样转换CS ...
- EasyShortcut Easyshortcut easyShortcut 简介
关于EasyShortcut Easyshortcut easyShortcut 简介: 参考: http://chunsheng.me/EasyShortcut/
- js复制对象 和 节点类型和NodeList
1. myList.cloneNode(true); 在参数为true的情况下,执行深复制,也就是复制节点及其整个子节点树,包括属性 2. myList.cloneNode(false); 在参数为f ...
- debian系统下安装ssh服务
它是什么?? SSH 为 Secure Shell 的缩写,简单地说,SSH 为建立在应用层基础上的安全协议.SSH 是目前较可靠,专为远程登录会话和其他网络服务提供安全性的协议.利用 SSH 协议可 ...
- js 日常问题记录
1.解决ie6下css背景图不缓存 try{ document.execCommand('BackgroundImageCache',false,true); }catch(e){} 2.为ajax设 ...
- Effective Java2读书笔记-类和接口(一)
第13条:使类和成员的可访问性最小化 设计良好的模块的模块与设计不好的模块区别在于,设计良好的模块会隐藏所有的实现细节,把它的API与他的实现清晰地隔离开来.然后模块之间只通过API通信. 信息隐藏之 ...
- 董事长、总裁与CEO的区别与实质
自从信息产业兴起以来,尤其是网络股泡沫产生以来,“CEO”在中国骤然成为一个流行词汇.总经理和总裁们纷纷改称CEO,这个缩写词比它的中译版“首席执行官”更简洁,在中国人心目中更有神圣感,于是便出现了今 ...