oracle 行转列sql

合集下载

Oracle列转行和行转列的几种用法

Oracle列转行和行转列的几种用法

Oracle列转行和行转列的几种用法栏到栏主要讨论sys_connect_by_path的用法1,具有分层关系SQL > createtabledept(deptnononumber,deptname varchar2 (20),mgrnononumber);table created .SQL >插入deptvalues (1,“总部”,空);1 row created .SQL >插入deptvalues (2,’浙江分公司’,1);1 row created .SQL > insert into dept values(3,’杭州分公司’,2);已创建1行。

SQL >提交;提交完成。

SQL >从部门连接中选择最大值(子串(sys_connect_by_path(deptname,’,’),2))由先前部门连接= mgrno 最大值(SUBSTER(SYS _ CONNECT _ BY _ PATH(DEPTNAME),’),2)-总部,浙江分行,杭州分行2,行-列转换如果一个表的所有列都连接到一行,用逗号分隔:SQL >选择最大值(SUBSTER(SYS _ CONNECT _ BY _ PATH(column _ name,’,’),2))MAX(SUBSTRA(SYS _ CONNECT _ BY _ PATH(COLUMN _ NAME,’,’),2))- DEPTNO,DEPTNAME,MGRNO3,ListAgg(Oracle 11g)SQL >选择DEPTNO,2 ListAgg(NAME,’;’)3在组4内(由搪瓷订购)搪瓷5来自emp6组由deptno7由deptno 8 /DEPTNO搪瓷- -10 CLARK。

国王;米勒20亚当斯;福特。

琼斯;SCOTT。

史密斯30艾伦;布莱克;JAMES;马丁;TURNER;下面的W ARD是使用tempas的列转换1的两种用法(从t_cc_l2_employee 256中选择account_no,user_party_id,data_hierarchy_id+ where account_no不为空)从temp union中选择account _ no,user _ party _ id全部选择account _ no,data _ hierarchy _ id从temp 2 256中选择来自t_cc_l2_employee的data_hierarchy_id,其中account_no不为空,user_party_id不为空,data_hierarchy_id不为空)MODELRETURE UPDATED ROWSPARTITION BY(account _ no)DIMENSION BY(0 AS n) MEASURES(‘ xx ‘ AS cn,’ yyyyyy’ AS cv,user_party_id,data _ hierarchy _ id)RULES UPSERT ALL(cn[1-注意:模型语法SQL经常遇到两个问题1 ora-32638:模型维度中的非唯一寻址(问题是模型结果集中对应于分区依据的列具有重复值)2 ora-25137数据值超出范围(将“yyyyyyyy”中的“yyyyyyy”扩展几个位置可以解决您的问题)255。

sql语句行转列函数及其用法

sql语句行转列函数及其用法

sql语句行转列函数及其用法SQL语句行转列函数是一种用于将多个行数据转换为一列的函数。

它可以将一组多行数据中的某个列值,转换为以该列值为列名,其他列值为行值的形式。

在不同的数据库中,行转列函数的具体语法可能会有所不同。

以下是几种常用的行转列函数及其用法:1. MySQL中的GROUP_CONCAT函数:语法:GROUP_CONCAT(expression [ORDER BY clause] [SEPARATOR separator])用法:SELECT id, GROUP_CONCAT(name) AS namesFROM table GROUP BY id;说明:GROUP_CONCAT函数可以将指定列的值连接成一个字符串,并可通过ORDER BY子句指定排序规则,通过SEPARATOR参数指定分隔符。

2. Oracle中的LISTAGG函数:语法:LISTAGG(expression, separator) WITHIN GROUP (ORDER BY clause)用法:SELECT id, LISTAGG(name, ',') WITHIN GROUP (ORDER BY name) AS names FROM table GROUP BY id;说明:LISTAGG函数可以将指定列的值连接成一个字符串,并可通过ORDER BY子句指定排序规则,通过separator参数指定分隔符。

3. SQL Server中的STUFF函数:语法:STUFF ( character_expression , start , length , replaceWith_expression )用法:SELECT id, STUFF((SELECT ',' + name FROM table WHERE id = t.id FOR XML PATH('')), 1, 1, '') AS names FROM table t GROUP BY id;说明:STUFF函数可以将字符插入到另一个字符中的指定位置,并可以通过FOR XML PATH('')将行数据转换为一个字符串。

oracle中如何进行行转列,Oracle中的行转列例子详解

oracle中如何进行行转列,Oracle中的行转列例子详解

oracle中如何进⾏⾏转列,Oracle中的⾏转列例⼦详解--场景1:A Ba1a2a3b4b5希望实现如下效果:a1,2,3b4,5create table tmp asselect 'a' A, 1 B from dual union allselect 'a' A, 2 B from dual union allselect 'a' A, 3 B from dual union allselect 'b' A, 4 B from dual union allselect 'b' A, 5 B fromdual;1.⽅法1:listagg--listagg() + group by: 推荐使⽤select a,listagg(b,',') within group (order by b) as c from tmp group bya;--listagg() + over(partition by )select distinct a,listagg(b,',') within group (order by b) over(partition by a) as c fromtmp ;2.wm_concatselecta,to_char(wm_concat(b)) as b from tmp group bya3.sys_connect_by_pathselect a, max(substr(sys_connect_by_path(b, ','), 2)) strfrom (select a, b, row_number() over(partition by a order by b) rn fromtmp)startwith rn = 1connectby rn = prior rn + 1and a =prior agroup bya;4.max+decodeselecta,max(decode(rn, 1, b, null)) ||max(decode(rn, 2, ',' || b, null)) ||max(decode(rn, 3, ',' || b, null)) strfrom (select a,b,row_number() over(partition by a order by b) as rn fromtmp)group byaorder by1;5.row_number()+leadselect a, strbfrom (selecta,row_number()over(partition by a order by b) asrn,b|| lead(',' || b, 1) over(partition by a order by b) ||lead(',' || b, 2) over(partition by a order by b) ||lead(',' || b, 3) over(partition by a order by b) as strfromtmp)where rn = 1order by 1;6.model语句select a, substr(str,2) bfromtmpmodelreturn updated rows partition by(a) dimension by(row_number() over(partition by a order by b) asrn)measures(cast(b as varchar2(20)) as str)rules upsert iterate(3) until(presentv(str[iteration_number+2],1,0) = 0)(str[0] = str[0]||','||str[iteration_number + 1])order by 1;--场景2:no sex004 2002 2002 2003 1002 1希望实现如下效果:c1 c2002 1 2003 1 0004 0 1也就是说按no sex两个字段count⼈数,得到⼆维表。

oracle行转列公式

oracle行转列公式

oracle行转列公式在Oracle数据库中,要将行转换为列,可以使用PIVOT操作符。

PIVOT操作符可以将行数据转换为列数据,这在需要对数据进行透视分析时非常有用。

下面我将介绍如何使用PIVOT操作符来实现行转列的功能。

首先,假设我们有一个名为EMPLOYEE的表,其中包含员工的姓名、部门和工资信息。

我们想要将部门作为列,员工姓名作为行,显示每个员工在不同部门的工资情况。

下面是一个示例的SQL查询,演示了如何使用PIVOT操作符来实现行转列的功能:sql.SELECT.FROM.(SELECT employee_name, department_name, salary.FROM employee)。

PIVOT.(MAX(salary)。

FOR department_name IN ('部门A' AS A, '部门B' AS B, '部门C' AS C));在这个示例中,首先从EMPLOYEE表中选择员工的姓名、部门和工资信息。

然后使用PIVOT操作符将部门名称转换为列,使用MAX函数来对工资进行聚合。

最后,通过IN子句指定要转换为列的部门名称,并为每个部门指定一个别名。

执行以上查询后,将会得到一个结果集,其中员工姓名作为行,不同部门的工资信息作为列,每一行代表一个员工在不同部门的工资情况。

需要注意的是,PIVOT操作符在Oracle数据库中是比较灵活和强大的,可以根据实际需求进行各种数据透视分析操作。

当然,具体的操作还是要根据实际的数据表结构和需求来进行调整和修改。

希望以上信息能够帮助到你。

Oracle:Oracle行转列、列转行的Sql语句总结

Oracle:Oracle行转列、列转行的Sql语句总结

Oracle:Oracle⾏转列、列转⾏的Sql语句总结例⼦原型:select bkg_num,shpr_cde from CD_XLS_UPLOAD_DETAIL where cd_xls_upload_uuid='392' ;运⾏结果如下:⼀、多字段的拼接将两个或者多个字段拼接成⼀个字段:select bkg_num||shpr_cde from CD_XLS_UPLOAD_DETAIL where cd_xls_upload_uuid='392' ;运⾏结果:⼆、⾏转列将某个字段的多⾏结果,拼接成⼀个字段,获取拼接的字符串【默认逗号隔开】select wm_concat(bkg_num) from CD_XLS_UPLOAD_DETAIL where cd_xls_upload_uuid='392' ;运⾏结果:6098621760,6098621760开拓:如果不想⽤逗号隔开,可以进⾏替换:select replace(wm_concat(bkg_num),',','|') from test; 也可以进⾏分组的拼接:select id,wm_concat(bkg_num) name from test group by id;三、列转⾏原图如下:转成⾏的形式:实现的sql:create table demo(id int,name varchar(20),nums int); ---- 创建表insert into demo values(1, 'apple', 1000);insert into demo values(2, 'apple', 2000);insert into demo values(3, 'apple', 4000);insert into demo values(4, 'orange', 5000);insert into demo values(5, 'orange', 3000);insert into demo values(6, 'grape', 3500);insert into demo values(7, 'mango', 4200);insert into demo values(8, 'mango', 5500);commit;select name, sum(nums) from demo group by name;select * from (select name, nums from demo) pivot(sum(nums) for name in ('apple','orange','grape','mango')); --实现sql注意: pivot(聚合函数 for 列名 in(类型)),其中 in('') 中可以指定别名,in中还可以指定⼦查询,⽐如 select distinct code from customers指定别名如:select * from (select name, nums from demo) pivot(sum(nums) for name in ('apple' 苹果,'orange' 橘⼦,'grape' 葡萄,'mango' 芒果));。

oracleSql行转列方式

oracleSql行转列方式

oracleSql⾏转列⽅式姓名课程分数张三语⽂ 74张三数学 83张三物理 93李四语⽂ 74李四数学 84李四物理 94想变成(得到如下结果):姓名语⽂数学物理---- ---- ---- ----李四 74 84 94张三 74 83 93-------------------创建表:create table stu_score(name varchar(20),cource varchar(20),score int);INSERT INTO stu_score VALUES('zhangsan', '数学', 76);INSERT INTO stu_score VALUES('zhangsan', '语⽂', 77);INSERT INTO stu_score VALUES('zhangsan', '英语', 66);INSERT INTO stu_score VALUES('lisi', '数学', 45);INSERT INTO stu_score VALUES('lisi', '语⽂', 67);INSERT INTO stu_score VALUES('lisi', '英语', 99);步骤:1. 按姓名分组,分组查询字段为姓名和最⼤值2. 在最⼤值中设置:1. 如果你想查询语⽂成绩,那么就通过case或者if设置为正常值,将其与的分数设置为02. 对这个值取sum或者max3、IF(id='某值',value1,value2)value1:true时取值value2:false时取值4、如果在group by后加上WITH ROLLUP 将会统计出总值。

写法:SELECT ,SUM(IF(s.courcr='数学',score,0)) AS 数学,SUM(IF(s.courcr='语⽂',score,0)) AS 语⽂ ,SUM(IF(s.courcr='英语',score,0)) AS 英语 FROM stu_score s GROUP BY ;sql:SELECT st.true_name,aq.id ,aua.answer_scoreFROM assess aJOIN assess_paper ap ON a.paper_id=ap.idJOIN assess_question aq ON aq.paper_id=ap.idJOIN assess_rule_paper arp ON arp.assess_id=a.idJOIN assess_rule ar ON arp.rule_id=ar.idJOIN assess_user_answeraua ON aq.id=aua.question_idJOIN student st ON er_id=er_idJOIN classroom cr ON st.class_id=cr.class_idJOIN center c ON cr.center_id=c.center_idJOIN series_class sc ON sc.series_class_name=cr.series_name结果:true_nameidanswer_score冯慧 15冯慧 24冯慧 33冯慧 42冯慧 51张瑞雪11张瑞雪21张瑞雪31张瑞雪41张瑞雪51杨⽟茹13杨⽟茹23杨⽟茹33杨⽟茹43杨⽟茹53杨⽉圆14杨⽉圆24杨⽉圆34杨⽉圆44杨⽉圆54罗妃15罗妃25罗妃35罗妃45罗妃55唐志琦15唐志琦25唐志琦35唐志琦45唐志琦55刘江波15刘江波25刘江波35刘江波45刘江波55⾏转列的sql:SELECT true_name AS 姓名,SUM(IF(id='1',answer_score,0)) AS 问题1,SUM(IF(id='2',answer_score,0)) AS 问题2,SUM(IF(id='3',answer_score,0)) AS 问题3,SUM(IF(id='4',answer_score,0)) AS 问题4,SUM(IF(id='5',answer_score,0)) AS 问题5FROM (SELECT st.true_name,aq.id ,aua.answer_scoreFROM assess aJOIN assess_paper ap ON a.paper_id=ap.idJOIN assess_question aq ON aq.paper_id=ap.idJOIN assess_rule_paper arp ON arp.assess_id=a.idJOIN assess_rule ar ON arp.rule_id=ar.idJOIN assess_user_answeraua ON aq.id=aua.question_idJOIN student st ON er_id=er_idJOIN classroom cr ON st.class_id=cr.class_idJOIN center c ON cr.center_id=c.center_idJOIN series_class sc ON sc.series_class_name=cr.series_nameWHERE ar.rule_name='职业发展顾问的满意度调查php1301'AND c.center_name='北京亚运村中⼼') wsfGROUP BY true_name WITH ROLLUP ;结果:。

Oracle行转列、列转行的Sql语句总结

Oracle行转列、列转行的Sql语句总结

Oracle⾏转列、列转⾏的Sql语句总结多⾏转字符串这个⽐较简单,⽤||或concat函数可以实现SQL Code1 2select concat(id,username) str from app_user select id||username str from app_user字符串转多列实际上就是拆分字符串的问题,可以使⽤ substr、instr、regexp_substr函数⽅式字符串转多⾏使⽤union all函数等⽅式wm_concat函数⾸先让我们来看看这个神奇的函数wm_concat(列名),该函数可以把列值以","号分隔起来,并显⽰成⼀⾏,接下来上例⼦,看看这个神奇的函数如何应⽤准备测试数据 SQL Code1 2 3 4 5 6create table test(id number,name varchar2(20)); insert into test values(1,'a');insert into test values(1,'b');insert into test values(1,'c');insert into test values(2,'d');insert into test values(2,'e');效果1 : ⾏转列,默认逗号隔开SQL Code1select wm_concat(name) name from test;效果2: 把结果⾥的逗号替换成"|"SQL Code1select replace(wm_concat(name),',','|') from test;效果3: 按ID分组合并nameSQL Code1select id,wm_concat(name) name from test group by id;sql语句等同于下⾯的sql语句:SQL Code1 2 3 4 5 6-------- 适⽤范围:8i,9i,10g及以后版本( MAX + DECODE )select id,max(decode(rn, 1, name, null)) ||max(decode(rn, 2, ',' || name, null)) ||max(decode(rn, 3, ',' || name, null)) strfrom (select id,789101112131415161718192021222324252627282930313233343536 name,row_number () over(partition by id order by name) as rnfrom test) tgroup by idorder by 1;-------- 适⽤范围:8i,9i,10g 及以后版本 ( ROW_NUMBER + LEAD )select id, strfrom (select id,row_number () over(partition by id order by name) as rn,name || lead (',' || name, 1) over(partition by id order by name) ||lead (',' || name, 2) over(partition by id order by name) ||lead (',' || name, 3) over(partition by id order by name) as str from test)where rn = 1order by 1;-------- 适⽤范围:10g 及以后版本 ( MODEL )select id, substr (str, 2) strfrom test model return updated rows partition by (id) dimension by (row_number ()over(partition by id order by name) as rn) measures(cast (name as varchar2(20)) as str)rules upsert iterate (3) until(presentv(str [ iteration_number + 2 ], 1, 0) = 0)(str [ 0 ] = str [ 0 ] || ',' || str [ iteration_number + 1 ])order by 1;-------- 适⽤范围:8i,9i,10g 及以后版本 ( MAX + DECODE )select t.id id, max (substr (sys_connect_by_path(, ','), 2)) strfrom (select id, name, row_number () over(partition by id order by name) rnfrom test) tstart with rn = 1connect by rn = prior rn + 1and id = prior idgroup by t.id;懒⼈扩展⽤法:案例: 我要写⼀个视图,类似"create or replace view as select 字段1,...字段50 from tablename" ,基表有50多个字段,要是靠⼿⼯写太⿇烦了,有没有什么简便的⽅法? 当然有了,看我如果应⽤wm_concat 来让这个需求变简单,假设我的APP_USER 表中有(id,username,password,age )4个字段。

Oracle列转行和行转列的几种用法

Oracle列转行和行转列的几种用法

列转行主要讨论sys_connect_by_path的使用方法。

1、带层次关系SQL> create table dept(deptno number,deptname varchar2(20),mgrno number);Table created.SQL> insert into dept values(1,'总公司',null);1 row created.SQL> insert into dept values(2,'浙江分公司',1);1 row created.SQL> insert into dept values(3,'杭州分公司',2);1 row created.SQL> commit;Commit complete.SQL> select max(substr(sys_connect_by_path(deptname,','),2)) from dept connect by prior deptno=mgrno;MAX(SUBSTR(SYS_CONNECT_BY_PATH(DEPTNAME,','),2))--------------------------------------------------------------------------------总公司,浙江分公司,杭州分公司2、行列转换如把一个表的所有列连成一行,用逗号分隔:SQL> select max(substr(sys_connect_by_path(column_name,','),2))from (select column_name,rownumrn from user_tab_columns where table_name ='DEPT')start with rn=1 connect by rn=rownum ;MAX(SUBSTR(SYS_CONNECT_BY_PATH(COLUMN_NAME,','),2))-------------------------------------------------------------------------------- DEPTNO,DEPTNAME,MGRNO3、ListAgg(Oracle 11g)SQL> select deptno,2 listagg(ename, '; ' )3 within group4 (order by ename) enames5 from emp6 group by deptno7 order by deptno8 /DEPTNO ENAMES--------- -------------------10 CLARK; KING; MILLER20 ADAMS; FORD; JONES;SCOTT; SMITH30 ALLEN; BLAKE;JAMES; MARTIN;TURNER; WARD下面是列转行的二个用法1with temp as (select account_no, user_party_id, data_hierarchy_id from t_cc_l2_employeewhereaccount_no is not null)selectaccount_no, user_party_id from tempunion allselectaccount_no, data_hierarchy_id from temp2SELECT account_no, cn, cv FROM (select distinct account_no, user_party_id, data_hierarchy_id from t_cc_l2_employeewhereaccount_no is not nullanduser_party_id is not nullanddata_hierarchy_id is not null)MODELRETURN UPDATED ROWSPARTITION BY (account_no)DIMENSION BY (0 AS n)MEASURES ('xx' AS cn,'yyyyyy' AS cv, user_party_id, data_hierarchy_id)RULES UPSERT ALL(cn[1] = 'c1',cn[2] = 'c2',cv[1] = user_party_id[0],cv[2] = data_hierarchy_id[0])ORDER BY account_no,cn;-- 注意点:model语法SQL经常会遇到二个问题1 ORA-32638: Non unique addressing in MODEL dimensions (问题出在被Model的结果集中的partition by对应的column有重复值)2 ORA-25137 Data value out of range (将'yyyyyy' AS cv 中的'yyyyyy' 扩大几位就可能解决您的问题了)。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

表结构和数据如下(表名Test):
NO V ALUE NAME
1 a 测试1
1 b 测试2
1 c 测试3
1 d 测试4
2 e 测试5
4 f 测试6
4 g 测试7
Sql语句:
select No,
ltrim(max(sys_connect_by_path(Value, ';')), ';') as Value,
ltrim(max(sys_connect_by_path(Name, ';')), ';') as Name
from (select No,
Value,
Name,
rnFirst,
lead(rnFirst) over(partition by No order by rnFirst) rnNext from (select a.No,
a.Value,
,
row_number() over(order by a.No, a.V alue desc) rnFirst
from Test a) tmpTable1) tmpTable2
start with rnNext is null
connect by rnNext = prior rnFirst
group by No;
检索结果如下:
NO V ALUE NAME
1 a;b;c;d 测试1;测试2;测试3;测试4
2 e 测试5
4 f;g 测试6;测试7
简单解释一下那个Sql吧:
1、最内层的Sql(即表tmpTable1),按No和Value排序,并列出行号:select a.No,
a.Value,
,
row_number() over(order by a.No, a.V alue desc) rnFirst
from Test a
该语句结果如下:
NO V ALUE NAME RNFIRST
1 d 测试4 1
1 c 测试3 2
1 b 测试
2 3
1 a 测试1 4
2 e 测试5 5
4 g 测试7 6
4 f 测试6 7
2、外层的Sql(即表tmpTable2),根据No分区,取出当前行对应的下一条记录的行号字段:select No,
Value,
Name,
rnFirst,
lead(rnFirst) over(partition by No order by rnFirst) rnNext
from (这里是tmpTable1的SQL) tmpTable1
lead(rnFirst):取得下一行记录的rnFirst字段
over(partition by No order by rnFirst) 按rnFirst排序,并按No分区,分区就是如果下一行的No字段与当前行的No字段不相等时,不取下一行记录显示
该语句结果如下:
NO V ALUE NAME RNFIRST RNNEXT
1 d 测试4 1 2
1 c 测试3
2 3
1 b 测试
2
3 4
1 a 测试1 4 NULL
2 e 测试5 5 NULL
4 g 测试7 6 7
4 f 测试6 7 NULL
3、最后就是最外层的sys_connect_by_path函数与start递归了
sys_connect_by_path(Value, ';')
start with rnNext is null
connect by rnNext = prior rnFirst
这个大概意思就是从rnNext为null的那条记录开始,递归查找,
如果前一记录的rnFirst字段等于当前记录的rnNext字段,就把2条记录的Value用分号连接起来,
大家可以先试试下面这个没有Max和Group的Sql:
select No,
sys_connect_by_path(Value, ';') as Value,
sys_connect_by_path(Name, ';') as Name
from (select No,
Value,
Name,
rnFirst,
lead(rnFirst) over(partition by No order by rnFirst) rnNext
from (select a.No,
a.Value,
,
row_number() over(order by a.No, a.V alue desc) rnFirst
from Test a) tmpTable1) tmpTable2
start with rnNext is null
connect by rnNext = prior rnFirst
结果是:
NO V ALUE NAME
1 ;a ;测试1
1 ;a;b ;测试1;测试2
1 ;a;b;c ;测试1;测试2;测试3
1 ;a;b;c;d ;测试1;测试2;测试3;测试4
2 ;e ;测试5
4 ;f ;测试6
4 ;f;g ;测试6;测试7
可以看到,每个No的最后一条记录就是我们要的了
所以在sys_connect_by_path外面套一个Max,再加个Group by No,得到的结果就是行转列的结果了
最后再加一个Ltrim,去掉最前面的那个分号,完成。

create or replace procedure ptest as
strname varchar2(30);
str varchar2(1000);
strid varchar2(10);
cursor cur is select * from userid;
begin
str:= ' ';
open cur;
loop
fetch cur into strid,strname;
exit when cur%notfound;
str:=str||strname|| ', ';
end loop;
str:=substr(str,1,length(str)-1);
dbms_output.put_line(str); end;。

相关文档
最新文档