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

合集下载

oracle行列转换总结

oracle行列转换总结
适用范围:8i,9i,10g及以后版本
SELECT id,
MAX(decode(cn, 'c1', cv, NULL)) AS c1,
MAX(decode(cn, 'c2', cv, NULL)) AS c2,
MAX(decode(cn, 'c3', cv, NULL)) AS c3
cv_pair('c3', t_col_row.c3))) t
ORDER BY 1, 2;
2、行转列
CREATE TABLE t_row_col AS
SELECT id, 'c1' cn, c1 cv
FROM t_col_row
UNION ALL
ID INT,
c1 VARCHAR2(10),
c2 VARCHAR2(10),
c3 VARCHAR2(10));
INSERT INTO t_col_row VALUES (1, 'v11', 'v21', 'v31');
INSERT INTO t_col_row VALUES (2, 'v12', 'v22', NULL);
适用范围:8i,9i,10g及以后版本
SELECT id, 'c1' cn, c1 cv
FROM t_col_row
UNION ALL
SELECT id, 'c2' cn, c2 cv
FROM t_col_row
UNION ALL
SELECT id, 'c3' cn, c3 cv FROM t_col_row;

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。

oracle中的行列转换

oracle中的行列转换

oracle中的⾏列转换在oracle⽰例数据库scott下执⾏select empno,ename,job,sal,deptno from emporder by deptno,job;--⾏转列--现在查询各部门各⼯种的总薪⽔select deptno, job, sum(sal) total_sal from empgroup by deptno, job order by1, 2;--但是这样不直观,如果能够把每个⼯种作为1列显⽰就会更⼀⽬了然.--这就是需要⾏转列。

--在11g之前,需要⼀点技巧,利⽤decode函数才能完成这个⽬标。

select deptno,sum(decode(job, 'PRESIDENT', sal, 0)) as PRESIDENT_SAL,sum(decode(job, 'MANAGER', sal, 0)) as MANAGER_SAL,sum(decode(job, 'ANALYST', sal, 0)) as ANALYST_SAL,sum(decode(job, 'CLERK', sal, 0)) as CLERK_SAL,sum(decode(job, 'SALESMAN', sal, 0)) as SALESMAN_SALfrom emp group by deptno order by1; select deptno,sum(case when job='PRESIDENT'then sal else0end) as PRESIDENT_SAL,sum(case when job='MANAGER'then sal else0end) as MANAGER_SAL,sum(case when job='ANALYST'then sal else0end) as ANALYST_SAL,sum(case when job='CLERK'then sal else0end) as CLERK_SAL,sum(case when job='SALESMAN'then sal else0end) as SALESMAN_SALfrom emp group by deptno order by1; --如果要在变回前⾯的结果,需要⽤到笛卡尔乘积,⼀⾏变五⾏,然后利⽤decode。

oracle的行转列函数

oracle的行转列函数

oracle的行转列函数Oracle是一种现代化、高效的数据库管理系统,它在行列转换方面有着强大的转换函数和工具。

行列转换函数是Oracle数据库中的一个重要组成部分,它可以用来将行数据转换为列数据,或将列数据转换为行数据,这在业务分析、数据挖掘等方面都有着极大的用处。

本文将简要介绍Oracle中的行列转换函数。

1. UNPIVOT函数UNPIVOT函数可以将一张带有多个列的表,转换为只有两列的表,其中一列是原来表格的列名,另一列是原来表格这一列的值。

UNPIVOT函数的语法如下:```SELECT *FROM table_name UNPIVOT((value1, 'column1') FOR column1 IN (column2, column3, ...),(value2, 'column2') FOR column2 IN (column3, column4, ...),...);```其中,table_name代表要转换的表格的名称,columnX代表原表格中的列名,valueX代表原表格中的值。

例如,若原表格中有A、B、C、D四个列,包含多行数据,那么可以使用以下语句将其转换为只有两列的表:该语句将生成两列,一列为name,包含了A、B、C、D四个列的名称,另一列为value,包含了相应列的值。

这样就可以方便地进行数据分析了。

该语句将生成一列key,表示原表格中的唯一关键字列,另外还有A、B、C三列,表示原表格中包含的三个列,每行记录表示一个唯一的key值和对应的A、B、C三个列的值。

3. CROSS JOIN函数CROSS JOIN函数可以将两个表中的每一个记录都做一个笛卡尔积,生成一个新表。

例如,若有两个表T1和T2,T1有列A、B,T2有列C、D,可以使用以下语句将它们进行笛卡尔积,生成一个新表:```SELECT *FROM T1CROSS JOIN T2;```该语句将生成一个新表,包含了所有T1和T2中的记录的笛卡尔积。

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一列转多行最简单的方法在Oracle SQL中,有多种方法可以将一列数据转换为多行。

以下是几种最简单的方法:1.使用UNIONALL操作符:可以使用UNIONALL操作符将多个SELECT语句的结果合并成一个结果集,从而将一列数据转换为多行。

每个SELECT语句都应该只返回一行数据,并且列数和数据类型必须匹配。

例如,假设我们有一个表单名为employees,其中有一个列名为name,包含多个员工的姓名。

我们可以使用以下语句将该列转换为多行:```sqlSELECT name FROM employeesUNIONALLSELECT name FROM employeesUNIONALLSELECT name FROM employees;```这将返回一个包含所有姓名的结果集。

2.使用CONNECTBYLEVEL子句:CONNECTBYLEVEL子句可以用于生成指定的行数,然后通过连接其他表获取相关的数据。

在这种情况下,我们可以使用CONNECTBYLEVEL子句生成多行,然后连接到原始表以获取实际数据。

例如,使用以下语句生成从1到10的数字序列:```sqlSELECTLEVELFROM dualCONNECTBYLEVEL<=10;```然后,我们可以使用该序列连接到原始表中获取实际数据:```sqlSELECT FROM employees eJOIN (SELECT LEVEL AS numFROM dualCONNECTBYLEVEL<=10)lON l.num = e.employee_id;```这将返回一个包含10个姓名的结果集,每个重复10次。

3.使用PIVOT操作:如果我们希望将一列数据转换为多行,并且我们知道有限的可能值,可以使用PIVOT操作。

这要求我们事先知道有多少个可能的值,并且使用CASE语句或PIVOT运算符将每个可能的值转换为一个列。

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' 扩大几位就可能解决您的问题了)。

Oracle专题-11G列转行

Oracle 专题-11G 列转行一、列转行上期讲述了行转列 PIVOT,本期讲述它的反向操作-列转行 Unpivot。

假设有一个显示交叉表报表的电子表格(cust_matrix),如下所示: Puchase_Frequency New_York Conn New_Jersey Florida 1 2 3 4 ... and so on 33048 33151 32978 33109 ... 165 0 179 0 173 0 173 0 0 0 0 1 Missouri 0 0 0 0这是数据在电子表格中的存储方式: 每个州是表中的一个列 (如 New_York、 Conn 等等) 。

要转化为如下结构的数据表 customers(行仅显示州代码和该州的购物人数): Puchase_Frequency STATE_CODE STATE_COUNTS ----------------- ---------- -----------1 Conn 165 1 Florida 0 1 Missouri 0 1 New_Jersey 0 1 New_York 33048 2 Conn 179 2 Florida 0 2 Missouri 0 ... and so on ... 可以使用 DECODE 编写一个复杂 SQL 脚本,将数据加载到 CUSTOMERS 表中。

或者,可以 使用 pivot 的反向操作 UNPIVOT,将列打乱变为行,这在 Oracle 数据库 11g 中可以实现。

通过 unpivot 操作可以达到此目的,如下所示: SELECT * FROM cust_matrix unpivot(state_counts FOR state_code IN(New_York,Conn,New_Jersey,Florida,Missouri)) ORDER BY Puchase_Frequency, state_code;注意每个列名如何变为 STATE_CODE 列中的一个值。

oracle的行转列函数

oracle的行转列函数Oracle的行转列函数是指将一些列的多个行值转换为一行,通常用于将多行数据合并成单行数据,以便于进行数据汇总或者分析。

在Oracle中,行转列的主要方法有使用PIVOT和UNPIVOT函数以及使用CASE语句进行条件判断。

1.使用PIVOT函数PIVOT函数用于将行数据转换为列数据。

它的语法如下:PIVOT聚合函数FOR列名IN('列值1'AS'新列名1','列值2'AS'新列名2',...);例如,假设有一个表student,包含了姓名(name)、课程(course)和分数(score)三个字段,如下所示:name course score-----------------------Alice Math 85Alice Chinese 90Alice English 95Bob Math 80Bob Chinese 75Bob English 85现在我们希望将每个学生的课程及其对应的分数转换为一行数据,可以使用如下的PIVOT语句:SELECT*FROMSELECT name, course, scoreFROM studentPIVOTAVG(score) -- 可以是其他聚合函数,如SUM、MAX等FOR courseIN ('Math' AS Math, 'Chinese' AS Chinese, 'English' AS English);执行该查询后,将得到如下的结果:name Math Chinese English-------------------------------Alice 85 90 95Bob 80 75 852.使用UNPIVOT函数UNPIVOT函数是PIVOT函数的逆操作,用于将列数据转换为行数据。

它的语法如下:UNPIVOT转换列名FOR列名IN(新列名1AS'列值1',新列名2AS'列值2',...);例如,假设有一个表student,包含了姓名(name)、Math、Chinese 和English三个科目的分数,我们希望将这三个科目的分数转换为一列数据,可以使用如下的UNPIVOT语句:SELECT*FROMSELECT name, Math, Chinese, EnglishFROM studentUNPIVOTscoreFOR courseIN (Math AS 'Math', Chinese AS 'Chinese', English AS'English');执行该查询后,将得到如下的结果:name course score---------------------Alice Math 85Alice Chinese 90Alice English 95Bob Math 80Bob Chinese 75Bob English 853.使用CASE语句进行条件判断除了使用PIVOT和UNPIVOT函数外,我们还可以使用CASE语句进行条件判断,实现行转列的功能。

oracle行转列,列转行函数的使用(listagg,xmlagg)

oracle⾏转列,列转⾏函数的使⽤(listagg,xmlagg)⼀、⾏转列listagg函数:场景:这⾥的表数据使⽤的是oracle默认的scott账户下的emp(员⼯)表。

规范写法 : LISTAGG(字段, 连接符) WITHIN GROUP (ORDER BY 字段)通常情况下,LISTAGG是满⾜需要的,LISTAGG 返回的是⼀个varchar2类型的数据,最⼤字节长度为4000。

所以,在实际开发中,我们可能会遇到⼀个问题,连接长度过长。

在这个时候,我们需要将LISTAGG函数改成XMLAGG函数。

XMLAGG返回的类型为CLOB,最⼤字节长度为32767。

LISTAGG例⼦:1、使⽤条件查询部门号为20号的员⼯:-- 查询部门为20的员⼯列表SELECT t.DEPTNO,t.ENAME FROM SCOTT.EMP t where t.DEPTNO ='20' ;2、使⽤listagg() WITH GROUP()将多⾏合并成⼀⾏(⽐较常⽤)SELECTT.DEPTNO,listagg (T.ENAME, ',') WITHIN GROUP (ORDER BY T.ENAME) namesFROMSCOTT.EMP TWHERET.DEPTNO ='20'GROUP BYT.DEPTNO3、使⽤listagg() width group() over将多⾏记录在⼀⾏显⽰(不常⽤)SELECTT .DEPTNO,listagg (T .ENAME, ',') WITHIN GROUP (ORDER BY T .ENAME) over(PARTITION BY T .DEPTNO)FROMSCOTT.EMP TWHERET .DEPTNO ='20'⼆、XMLAGG函数的例⼦:XMLAGG(XMLPARSE(CONTENT BSO.ID || ',' WELLFORMED) ORDER BY BSO.ID).GETCLOBVAL()规划写法: XMLAGG(XMLPARSE(CONTENT 字段 || 字符串 WELLFORMED) ORDER BY 字段).GETCLOBVAL()三、对于mysql相同的效果实现,可以使⽤group_concat() 函数,详情可参考:mysql相同效果的实现 https:///sinat_36257389/article/details/95052001PostgreSQL 相同效果的实现 https:///sinat_36257389/article/details/95611686转⾃:,转载请注明来源。

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

列转行
主要讨论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,MGRNO
3、ListAgg(Oracle 11g)
SQL> select deptno,
2 listagg(ename, '; ' )
3 within group
4 (order by ename) enames
5 from emp
6 group by deptno
7 order by deptno
8 /
DEPTNO ENAMES
--------- -------------------
10 CLARK; KING; MILLER
20 ADAMS; FORD; JONES;
SCOTT; SMITH
30 ALLEN; BLAKE;
JAMES; MARTIN;
TURNER; WARD
下面是列转行的二个用法
1
with temp as (select account_no, user_party_id, data_hierarchy_id from t_cc_l2_employee
whereaccount_no is not null)
selectaccount_no, user_party_id from temp
union all
selectaccount_no, data_hierarchy_id from temp
2
SELECT account_no, cn, cv FROM (
select distinct account_no, user_party_id, data_hierarchy_id from t_cc_l2_employee
whereaccount_no is not null
anduser_party_id is not null
anddata_hierarchy_id is not null)
MODEL
RETURN UPDATED ROWS
PARTITION 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' 扩大几位就可能解决您的问题了)。

相关文档
最新文档