当前位置:文档之家› Oracle行转列,列转行

Oracle行转列,列转行

Oracle行转列,列转行
Oracle行转列,列转行

先来个简单的用法

列转行

Create table test (name char(10),km char(10),cj int)

insert test values('张三','语文',80)

insert test values('张三','数学',86)

insert test values('张三','英语',75)

insert test values('李四','语文',78)

insert test values('李四','数学',85)

insert test values('李四','英语',78)

select name,

sum(decode(km,'语文',CJ,0)) 语文,

sum(decode(km,'数学',cj,0)) 数学,

sum(decode(km,'英语',cj,0)) 英语

from test1

group by name

姓名语文数学英语

张三80 86 75

李四78 85 78

行转列

with x as( selectname,

sum(decode(km,'语文',CJ,0)) 语文 ,

sum(decode(km,'数学',cj,0)) 数学,

sum(decode(km,'英语',cj,0)) 英语

fromtest

groupbyname)

selectname,decode(rn,1, '语文', 2, '数学', 3,'英语') 课程, decode(rn, 1, 语文, 2, 数学, 3,英语) 分数

from x, (selectlevel rn from dual connectby1=1andlevel<=3) (from 后面接两个表,是笛卡尔积)

多行转字符串

这个比较简单,用||或concat 函数可以实现

?

1 2 3 selectconcat(id,username) str fromapp_user

selectid||username str fromapp_user

字符串转多列

实际上就是拆分字符串的问题,可以使用 substr 、instr 、regexp_substr 函数方式

字符串转多行

使用union all 函数等方式

wm_concat 函数

首先让我们来看看这个神奇的函数wm_concat (列名),该函数可以把列值以","号分隔起来,并显示成一行,接下来上例子,看看这个神奇的函数如何应用准备测试数据

?

1 2 3 4 5 6 7 createtabletest(id number,namevarchar2(20));

insertintotest values(1,'a');

insertintotest values(1,'b');

insertintotest values(1,'c');

insertintotest values(2,'d');

insertintotest values(2,'e');

效果1 : 行转列 ,默认逗号隔开

?

1 s electwm_concat(name) namefromtest;

效果2: 把结果里的逗号替换成"|"

?

1 s electreplace(wm_concat(name),',','|') fromtest;

效果3: 按ID 分组合并name

?

1 s electid,wm_concat(name) namefromtest groupbyid;

sql 语句等同于下面的sql 语句

?

1 2 3 4 5 6 7 8 9 10 11 -------- 适用范围:8i,9i,10g 及以后版本 ( MAX + DECODE ) selectid, max(decode(rn, 1, name, null)) || max(decode(rn, 2, ','|| name, null)) || max(decode(rn, 3, ','|| name, null)) str from(selectid,name,row_number() over(partition byid orderbyname) asrn fromtest) t groupbyid orderby1;

-------- 适用范围:8i,9i,10g 及以后版本 ( ROW_NUMBER + LEAD ) selectid, str from(selectid,row_number() over(partition byid orderbyname) asrn,name|| lead(','|| name, 1) over(partition byid orderbyname) ||

lead(','|| name, 2) over(partition byid orderbyname) ||

12 13 14 15 lead(','|| name, 3) over(partition byid orderbyname) asstr fromtest) wherern = 1 orderby1;

-------- 适用范围:10g 及以后版本 ( MODEL )

selectid, substr(str, 2) str fromtest model returnupdated

rowspartition by(id) dimension by(row_number() over(partition byid orderbyname) asrn)

measures (cast(nameasvarchar2(20)) asstr) rules upsert

iterate(3) until(presentv(str[iteration_number+2],1,0)=0) (str[0] = str[0] || ','|| str[iteration_number+1])

orderby1;

-------- 适用范围:8i,9i,10g 及以后版本 ( MAX + DECODE ) selectt.id id,max(substr(sys_connect_by_path(https://www.doczj.com/doc/292837795.html,,','),2)) str from(selectid, name, row_number() over(partition byid orderbyname) rn fromtest) t

start withrn = 1 connectbyrn = priorrn + 1 andid = priorid groupbyt.id;

懒人扩展用法:

案例: 我要写一个视图,类似"create or replace view as select 字段1,...字段50 from tablename" ,基表有50多个字段,要是靠手工写太麻烦了,有没有什么简便的方法? 当然有了,看我如果应用wm_concat 来让这个需求变简单,假设我的APP_USER 表中有(id,username,password,age )4个字段。查询结果如下

?

1 2 /** 这里的表名默认区分大小写 */

select'create or replace view as select '||

wm_concat(column_name) || ' from APP_USER'sqlStr

fromuser_tab_columns wheretable_name='APP_USER';

利用系统表方式查询

?

1 s elect* fromuser_tab_columns

Oracle 11g 行列互换 pivot 和 unpivot 说明

在Oracle 11g 中,Oracle 又增加了2个查询:pivot (列转行) 和unpivot (行转列)

参考:https://www.doczj.com/doc/292837795.html,/tianlesoftware/article/details/7060306、https://www.doczj.com/doc/292837795.html,/technetwork/cn/articles/11g-pivot-101924-zhs.html

google 一下,网上有一篇比较详细的文档:

https://www.doczj.com/doc/292837795.html,/display.php?id=506

pivot 列转行

测试数据 (id ,类型名称,销售数量),案例:根据水果的类型查询出一条数据显示出每种类型的销售数量。

?

1 2 3 4 5 6 7 8 9 createtabledemo(id int,namevarchar(20),nums int);

---- 创建表

insertintodemo values(1, '苹果', 1000);

insertintodemo values(2, '苹果', 2000);

insertintodemo values(3, '苹果', 4000);

insertintodemo values(4, '橘子', 5000);

insertintodemo values(5, '橘子', 3000);

insertintodemo values(6, '葡萄', 3500);

insertintodemo values(7, '芒果', 4200);

insertintodemo values(8, '芒果', 5500);

分组查询 (当然这是不符合查询一条数据的要求的)

?

1 s electname, sum(nums) nums fromdemo groupbyname

列转行查询

?

1 select* from(selectname, nums fromdemo) pivot (sum(nums) fornamein('苹果'苹果, '橘子', '葡萄', '芒果'));

注意: pivot (聚合函数 for 列名 in (类型)) ,其中 in(‘’) 中可以指定别名,in 中还可以指定子查询,比如 select distinct code from customers

当然也可以不使用pivot 函数,等同于下列语句,只是代码比较长,容易理解

?

1 2 select* from (selectsum(nums) 苹果 fromdemo wherename='苹果'),(selectsum(nums) 橘子 fromdemo wherename='橘子'),

(selectsum(nums) 葡萄 fromdemo wherename='葡萄'),(selectsum(nums) 芒果 fromdemo wherename='芒果');

unpivot 行转列

顾名思义就是将多列转换成1列中去

案例:现在有一个水果表,记录了4个季度的销售数量,现在要将每种水果的每个季度的销售情况用多行数据展示。

创建表和数据

?

1

2 3

4 5 6 7 createtableFruit(id int,namevarchar(20), Q1 int, Q2 int, Q3 int, Q4 int); insertintoFruit values(1,'苹果',1000,2000,3300,5000); insertintoFruit values(2,'橘子',3000,3000,3200,1500); insertintoFruit values(3,'香蕉',2500,3500,2200,2500); insertintoFruit values(4,'葡萄',1500,2500,1200,3500); select* fromFruit

行转列查询

?

1 selectid , name, jidu, xiaoshou fromFruit unpivot (xiaoshou forjidu in(q1, q2, q3, q4) )

注意: unpivot 没有聚合函数,xiaoshou 、jidu 字段也是临时的变量

同样不使用unpivot 也可以实现同样的效果,只是sql 语句会很长,而且执行速度效率也没有前者高

?

1 2 3 4 5 6 7 selectid, name,'Q1'jidu, (selectq1 fromfruit whereid=f.id) xiaoshou fromFruit f

union

selectid, name,'Q2'jidu, (selectq2 fromfruit whereid=f.id) xiaoshou fromFruit f

union

selectid, name,'Q3'jidu, (selectq3 fromfruit whereid=f.id) xiaoshou fromFruit f

union

selectid, name,'Q4'jidu, (selectq4 fromfruit whereid=f.id) xiaoshou fromFruit f

XML 类型

上述pivot 列转行示例中,你已经知道了需要查询的类型有哪些,用in()的方式包含,假设如果您不知道都有哪些值,您怎么构建查询呢?

pivot 操作中的另一个子句 XML 可用于解决此问题。该子句允许您以 XML 格式创建执行了 pivot 操作的输出,在此输出中,您可以指定一个特殊的子句 ANY 而非文字值

示例如下:

?

1 2 3 4 5 6 7 select* from(

selectname, nums as"Purchase Frequency"

fromdemo t

) pivot xml (

sum(nums) fornamein(any)

)

如您所见,列 NAME_XML 是 XMLTYPE ,其中根元素是 。每个值以名称-值元素对的形式表示。您可以使用任何 XML 分析器中的输出生成更有用的输出。

结论

Pivot 为 SQL 语言增添了一个非常重要且实用的功能。您可以使用 pivot 函数针对任何关系表创建一个交叉表报表,而不必编写包含大量 decode 函数的令人费解的、不直观的代码。同样,您可以使用 unpivot 操作转换任何交叉表报表,以常规关系表的形式对其进行存储。Pivot 可以生成常规文本或 XML 格式的输出。如果是 XML 格式的输出,您不必指定 pivot 操作需要搜索的值域。

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,MGRNO 3,ListAgg(Oracle 11g) SQL >选择DEPTNO, 2 ListAgg(NAME,’;’) 3在组 4内(由搪瓷订购)搪瓷 5来自emp 6组由deptno 7由deptno 8 / DEPTNO搪瓷 - - 10 CLARK。国王;米勒 20亚当斯;福特。琼斯; SCOTT。史密斯 30艾伦;布莱克; JAMES;马丁; TURNER;下面的W ARD

sqlserver到oracle数据无损迁移

sqlserver到oracle数据无损迁移 编者:liuli10@https://www.doczj.com/doc/292837795.html, 版本:V1.7 最后修订日期:2015-11-21

第一章简介 1.1数据迁移 随着时代发展数据越来越被重视,而很多时候,当系统需要更新换代的时候,升级后系统所是有的数据库与当前系统的数据库并不一致,此时不仅需要数据割接,最重要的是:如何能将老系统中的数据无损的割接到新系统、新数据库中。因此,结合项目实战经验,针对从windows平台下数据库sqlserver到linux平台下oracle数据库的数据无损迁移进行总结。 1.2数据库简介 一般此处会有很多数据库以及出品公司的历史以及发展历程,在编者看来然而并没有什么大用途,百度百科都可以搜索的到,因此本章结束,直接进入实战总结环节。

第二章sqlserver数据导出 2.1sqlserver数据导出命令 当然不可否认windows为sqlserver提供了强大的图形化平台,导出数据变得只需要点一点就能完成,然而这样的数据导出对于大批量有要求的操作,是极其劳神伤财的,因此,必须要通过命令行进行格式化导出,因此,这里介绍sqlserver 本机数据库导出命令。 2.1.1bcp命令以及参数介绍 https://www.doczj.com/doc/292837795.html,/liyanmingkong/article/details/6087674 https://www.doczj.com/doc/292837795.html,/uid-25472509-id-4304562.html https://www.doczj.com/doc/292837795.html,/link?url=WV2JJM4JHxR7Qct8rr_-499zPc3aP_7E5rOt5l yEnG_Mj_tE9_-ZN1JPE2Vc2wRpkO8QkNGNLVznDfMgniCOnxXhK5jQppNpZk8 Jo1x8o23 为了将文档尽可能精简,bcp命令的参数以及介绍请自行去以上任意网址查询。或者自行baidu或者google搜索。 2.2实战语句解析 实战语句为: bcp"select*from gwbnboss.dbo.ACCOUNT_BUSINESS"queryout "C:\Users\liuli9\Desktop\sqlserverdata_mov\textfile\ACCOUNT_BUSINESS.txt"-c -r"{#$&}"-t"{@#$}"-S"127.0.0.1"-U"数据库用户名"-P"密码" 最终导出的结果存在于 C:\Users\liuli9\Desktop\sqlserverdata_mov\textfile\ACCOUNT_BUSINESS.txt 文件中,当出现“{#$&}”时表示接下来是下一行数据,出现“{@#$}”时表示接下来是下一列数据。将查询结果集完整导出,不对数据做任何格式化或者修改操作,保证数据的原生无损。

oracle列转行sql详细讲解

--当期时间贷款时间 SELECT DK_ID, max(substr(activeDate, 2)) activeDate FROM (SELECT DK_ID, sys_connect_by_path(activeDate, ',') activeDate FROM (SELECT DK_ID, activeDate, DK_ID || rn rchild, DK_ID || (rn - 1) rfather FROM (SELECT TEMP.DK_ID, --查询项目所在地树形结构全名 SELECT t.area_id, substr(sys_connect_by_path(t.area_name, '-'), 2) as allname , connect_by_root t.area_name as root, --是单一操作符,返回当前层的最顶层节点connect_by_isleaf as IsLeaf, --是伪列,判断当前层是否为叶子节点,1代表是,0代表否 level as lel --是伪列,显示当前节点层所处的层数 FROM dk_project_area_info t START WITH t.area_name = '项目所在地' CONNECT BY PRIOR t.area_id = t.area_pid SYS_CONNECT_BY_PATH 学习2008-09-08 10:59SELECT ename FROM scott.emp START WITH ename = 'KING' CONNECT BY PRIOR empno = mgr; 得到结果为:KING JONES SCOTT ADAMS FORD SMITH BLAKE ALLEN WARD MARTIN TURNER JAMES

oracle 行转列sql

表结构和数据如下(表名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, https://www.doczj.com/doc/292837795.html,, 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, https://www.doczj.com/doc/292837795.html,, row_number() over(order by a.No, a.V alue desc) rnFirst

ORACLE关于动态SQL的使用

关于动态SQL的使用-----摘录 内容摘要:在PL/SQL开发过程中,使用SQL,PL/SQL可以实现大部份的需求,但是在某些特殊的情况下,在PL/SQL中使用标准的SQL语句或DML语句不能实现自己的需求,比如需要动态建表或某个不确定的操作需要动态执行。这就需要使用动态SQL来实现。本文通过几个实例来详细的讲解动态SQL的使用。 本文适宜读者范围:Oracle初级,中级 系统环境: OS:windows2000Professional(英文版) Oracle:8.1.7.1.0 正文: 一般的PL/SQL程序设计中,在DML和事务控制的语句中可以直接使用SQL,但是DDL语句及系统控制语句却不能在PL/SQL中直接使用,要想实现在PL/SQL中使用DDL语句及系统控制语句,可以通过使用动态SQL来实现。 首先我们应该了解什么是动态SQL,在Oracle数据库开发PL/SQL块中我们使用的SQL分为:静态SQL语句和动态SQL语句。所谓静态SQL指在PL/SQL块中使用的SQL语句在编译时是明确的,执行的是确定对象。而动态SQL是指在PL/SQL块编译时SQL语句是不确定的,如根据用户输入的参数的不同而执行不同的操作。编译程序对动态语句部分不进行处理,只是在程序运行时动态地创建语句、对语句进行语法分析并执行该语句。 Oracle中动态SQL可以通过本地动态SQL来执行,也可以通过DBMS_SQL包来执行。下面就这两种情况分别进行说明: 一、本地动态SQL 本地动态SQL是使用EXECUTE IMMEDIATE语句来实现的。 1、本地动态SQL执行DDL语句: 需求:根据用户输入的表名及字段名等参数动态建表。 create or replace procedure proc_test ( table_name in varchar2,--表名 field1in varchar2,--字段名 datatype1in varchar2,--字段类型 field2in varchar2,--字段名 datatype2in varchar2--字段类型 )as str_sql varchar2(500); begin str_sql:=create table||table_name||(||field1||||datatype1||,||field2|| ||datatype2||); execute immediate str_sql;--动态执行DDL语句 exception when others then null; end; 以上是编译通过的存储过程代码。下面执行存储过程动态建表。

Oracle行转列,列转行

先来个简单的用法 列转行 Create table test (name char(10),km char(10),cj int) insert test values('张三','语文',80) insert test values('张三','数学',86) insert test values('张三','英语',75) insert test values('李四','语文',78) insert test values('李四','数学',85) insert test values('李四','英语',78) select name, sum(decode(km,'语文',CJ,0)) 语文, sum(decode(km,'数学',cj,0)) 数学, sum(decode(km,'英语',cj,0)) 英语 from test1 group by name 姓名语文数学英语 张三80 86 75 李四78 85 78 行转列 with x as( selectname, sum(decode(km,'语文',CJ,0)) 语文 , sum(decode(km,'数学',cj,0)) 数学, sum(decode(km,'英语',cj,0)) 英语 fromtest groupbyname) selectname,decode(rn,1, '语文', 2, '数学', 3,'英语') 课程, decode(rn, 1, 语文, 2, 数学, 3,英语) 分数 from x, (selectlevel rn from dual connectby1=1andlevel<=3) (from 后面接两个表,是笛卡尔积)

动态行列转换(列数不固定)

众所周知,静态SQL的输出结构必须也是静态的。对于经典的行转列问题,如果行数不定导致输出的列数不定,标准的答案就是使用动态SQL, 到11G里面则有XML结果的PIVOT。 今天在asktom看到的一篇贴子彻底颠覆了我的看法!贴子里的链接指向另一个牛人辈出的荷兰公司: http://technology.amis.nl/2006/0 ... ing-antons-thunder/ 还记得Anton Scheffer吗?这位神人先是用10G的MODEL写了SUDOKU的一句SQL的解法,在11GR2推出之后又率先用递归WITH写了个只有短短几行的SUDOKU解法。他的作品还有EXCEL文件生成器。 早在2006年他就发明了真正动态的行转列办法,用的是一系列神秘的函数,如同自定义聚合函数STRAGG里面用的那些。这个神秘的对象代码如下: 1.CREATE OR REPLACE 2.type PivotImpl as object 3.( 4.ret_type anytype,-- The return type of the table function 5.stmt varchar2(32767), 6.fmt varchar2(32767), 7.cur integer, 8.static function ODCITableDescribe( rtype out anytype, p_stmt in varchar2, p_fmt in varchar2 := 'upper(@p@)', dummy in number := 0 ) 9.return number, 10.static function ODCITablePrepare( sctx out PivotImpl, ti in sys.ODCITabFuncInfo, p_stmt in varchar2, p_fmt in varchar2 := 'upper(@p@)', dummy in number := 0 ) 11.return number, 12.static function ODCITableStart( sctx in out PivotImpl, p_stmt in varchar2, p_fmt in varchar2 := 'upper(@p@)', dummy in number := 0 ) 13.return number, 14.member function ODCITableFetch( self in out PivotImpl, nrows in number, outset out anydataset ) 15.return number, 16.member function ODCITableClose( self in PivotImpl ) 17.return number 18.) 19./ 20. 21.create or replace type body PivotImpl as 22.static function ODCITableDescribe( rtype out anytype, p_stmt in varchar2, p_fmt in varchar2 := 'upper(@p@)', dummy in number ) 23.return number 24.is 25.atyp anytype; 26.cur integer; 27.numcols number; 28.desc_tab dbms_sql.desc_tab2; 29.rc sys_refcursor; 30.t_c2 varchar2(32767); 31.t_fmt varchar2(1000); 32.begin 33.cur := dbms_sql.open_cursor; 34.dbms_sql.parse( cur, p_stmt, dbms_sql.native ); 35.dbms_sql.describe_columns2( cur, numcols, desc_tab ); 36.dbms_sql.close_cursor( cur ); 37.-- 38.anytype.begincreate( dbms_types.typecode_object, atyp ); 39.for i in 1 .. numcols - 2

oracle列转行

oracle列转行 1------------------------ 表结构: 1A 1B 1C 2A 2B 3C 3F 4D 转换后变成: 1A,B,C 2A,B 3C,F 4D 假设你的表结构是tb_name(id,remark),则语句如下:

SELECT a.id, wm_concat(a.remark)new_result FROM tb_name a group by a.id 2---------------------------------- 产品名称销售额季度 奶酪50第一季度 奶酪60第二季度 啤酒50第二季度 啤酒80第四季度 。。。 。。。 想转换成如下格式 产品名称第一季度销售额第二季度销售额第三季度销售额第四季度销售额 奶酪50600 0 啤酒0500

80 oracle下可以用函数decode处理: select产品名称, sum(decode(季度,'第一季度',销售额,0))第一季度销售额, sum(decode(季度,'第二季度',销售额,0))第二季度销售额, sum(decode(季度,'第三季度',销售额,0))第三季度销售额, sum(decode(季度,'第四季度',销售额,0))第四季度销售额, from表名 group by产品名称; 3------------------------------------------- oracle行转列的通用过程2010-04-0923:28经常遇到发帖求行列转换的代码,用max(decode(..))回复后,十有八九会再问一句:如果列名不固定,或者列数不固定怎么办。就要用存储过程来写,这些存储过程的代码都大同小异,我就想能不能写个通用点的过程

从业务数据库到元数据,SaaS 架构设计经验全总结

未来社会模型中 SaaS 的位置与分量 上图是一个从连接这个透视角度抽象出来的社会模型,其中的家庭、人、组织、物都是相互连接的,它也是一个从软件架构抽象出来的社会模型。SaaS 是对软件的获得和使用方式的革命,早在 2004 年就已有端倪(当时称为 ASP,Application Service Provider)。笔者认为,可以将 SaaS 放在社会运行机制、发展趋势这样的大格局中定位其社会作用。SaaS 企业也需要这样的格局与信念,虽然在中国还没有出现非常成功的 SaaS 企业,但终究会出现的,信任、习惯、规范、与能力都需要进化,需要时间。 在没有电之前,人们就有传递信息的需求,这也是为什么微信能够存在的本质根由。同理,各种组织都离不开软件,而且软件的渗透越来越广泛与深入,因为整个世界的数字化是不可阻挡的趋势。而 SaaS 在大部分情况下是必选之路,会越来越成为标配,除非特殊原因,或者不在乎成本、或者已经拥有某种等效的软件、或者其他原因。只要这种本质性的需求存在着,社会的发展终究会以越来越先进的方式来满足它。 这里分享一个关于云的小故事,笔者曾经算过一笔账,如果在云上订购托管机房中约 500 台机器的同等算力,每年需要支出 5000 万,相当有悖于流行认知,其实对于稍微有些规模的 IT 资源诉求,云相对是更加昂贵的,但来的快、方便,两方面都是事实。

这里只想传递一个观点,长远来看,SaaS 有它存在与发展的必然性。结构上讲,它是社会运行机制中不可或缺的一部分。同样或者类似的软件,显然没有必要每个人、每个组织都各买一套或各自开发一套,这是社会资源的极大浪费,有悖于社会发展的基本规律——既然是必需的,必然选择物美价廉。而且组织支出比个人支出更理性、更注重实用价值,有利可图的需求终究会达到稳态的、某种主流服务的满足。 从架构角度看 SaaS 面临的挑战 如果说 SaaS 在大部分情况下将会成为必选之路,那么它面临的最大挑战又是什么呢?概括来讲,SaaS 面临的最大挑战是满足客户的个性化需求。从架构角度看,它体现在如下图所示的几个方面: 其中最有挑战性的又要属多变的后台逻辑与数据模型。对于 SaaS 供应商而言,这种需求显然不能通过项目的方式来定制满足,而只有通过提供灵活的自服务平台才能满足,这种灵活性就需要用 PaaS 来生产客户想要的软件。这一点笔者在2013 年做一个 SaaS 项目的架构工作时就深有体会:一开始的目标也是做 SaaS,但是后来还是走上了 PaaS 的道路,不过是专为生产 SaaS 而自用的 PaaS,而不是定位于 PaaS 供应商。 如果一个 SaaS 企业从一开始就只是聚焦某个业务,而没有着手 PaaS 的建设,那说明它在满足个性化需求的道路上一定是在某个局部、某个层面解决问题,而不是系统、全面、可复用地解决问题。同时,从中国 SaaS 市场现状来看,它的成长比较慢,环境的综合成熟度还不够高,聚焦单一业务成长的加速度不够,因此企业后续很可能会从最开始聚焦的核心业务向外扩展,到时候又要面临种种个性化需求问题。因此,一个成功的 SaaS 企业必然要去寻求 PaaS 的支撑。从这两个意义上讲,PaaS 可能也是 SaaS 企业提高生产力的必经方向。据有关数据

oracle动态行转不定列

oracle----------行转列(动态行转不定列)----测试通过(9i) /*物料需要数量需要仓库现存量仓库现存量仓库数量批次 A1 2 C1 C1 20 123 A1 2 C1 C2 30 111 A1 2 C1 C2 20 222 A1 2 C1 C3 10 211 A2 3 C4 C1 40 321 A2 3 C4 C4 50 222 A2 3 C4 C4 60 333 A2 3 C4 C5 70 223 我需要把上面的查询结果转换为下面的。 物料需要数量需要仓库C1 C2 C3 C4 C5 A1 2 C1 20 50 10 0 0 A2 3 C4 40 0 0 110 70 */ ---------------------------------------------------------------建表 ----------------判断表是否存在 declare num number; begin select count(1) into num from user_tables where table_nam e='T EST'; if num>0 then execute immediate 'drop table TEST'; end if; end; ----------------建表 CREATE TABLE TEST( WL VARCHAR2(10), XYSL INTEGER, XYCK VARCHAR2(10),

XCLCK VARCHAR2(10), XCLCKSL INTEGER, PC INTEGER ); ----------------第一部分测试数据 INSERT INTO TEST VALUES('A1', 2, 'C1', 'C1' , 20, 123); INSERT INTO TEST VALUES('A1', 2, 'C1', 'C2' , 30, 111); INSERT INTO TEST VALUES('A1', 2, 'C1', 'C2' , 20, 222); INSERT INTO TEST VALUES('A1', 2, 'C1', 'C3' , 10, 211); INSERT INTO TEST VALUES('A2', 3, 'C4', 'C1' , 40, 321); INSERT INTO TEST VALUES('A2', 3, 'C4', 'C4' , 50, 222); INSERT INTO TEST VALUES('A2', 3, 'C4', 'C4' , 60, 333); INSERT INTO TEST VALUES('A2', 3, 'C4', 'C5' , 70, 223); COMMIT; --select * from test; ---------------------------------------------------------------行转列的存储过程CREATE OR REPLACE PROCEDURE P_TEST IS V_SQL VARCHAR2(2000); CURSOR CURSOR_1 IS SELECT DISTINCT T.XCLCK FROM TEST T ORDER BY XCLCK; BEGIN V_SQL := 'SELECT WL,XYSL,XYCK'; FOR V_XCLCK IN CURSOR_1 LOOP V_SQL := V_SQL || ',' || 'SUM(DECODE(XCLCK,''' || V_XCLCK.XCLCK || ''',XCLCKSL,0)) AS ' || V_XCLCK.XCLCK; END LOOP;

Oracle-casewhen用法-行列转换

Oracle 行列转换 1、固定列数的行列转换 如 转换为 语句如下: create table tb_chengji (student varchar2(20),subject varchar2(20),g rade num ber); select student, sum(case subject when'语文'then grade end)"语文", sum(case subject when'数学'then grade end)"数学", sum(case subject when'英语'then grade end)"英语", sum(grade) "总分" from tb_chengji group by student; 或者 select student, sum(decode(subject,'语文',grade,null)) "语文", sum(decode(subject,'数学',grade,null)) "数学", sum(decode(subject,'英语',grade,null)) "英语", sum(grade) "总分" from tb_chengji group by student; 2、不定列行列转换 如

c1 c2 --- ----------- 1 我 1 是 1 谁 2 知 2 道 3 不 …… 转换为 1 我是谁 2 知道 3 不 这一类型的转换可以借助于PL/SQL来完成,这里给一个例子 create table ttt (c1 number,c2 varchar2(10)); select*from ttt; create or replace function get_c2(tmp_c1 number) return varchar2 is col_c2 varchar2(4000); begin for cur in(select c2 from ttt where c1=tmp_c1)loop col_c2 := col_c2||cur.c2; end loop; col_c2 := rtrim(col_c2,1); return col_c2; end; select distinct c1 ,get_c2(c1) cc2 from ttt order by c1; 或者不用pl/sql,利用分析函数和CONNECT_BY 实现: select c1, substr (max(sys_connect_by_path (c2,';')),2)name from(select c1, c2, rn, lead (rn) over (partition by c1 order by rn) rn1 from(select c1, c2, row_number () over (order by c2) rn from ttt)) start with rn1 is null connect by rn1 =prior rn group by c1; 3、列数不固定(交叉表行列转置)

交叉表,行列转换,交叉查询经典,分组小计合计报表,SQL,

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ https://www.doczj.com/doc/292837795.html,/Render/archive/2006/12/19/596485.html 分组小计合计报表的SQL Table1结构如下: OrgName,StaffName, PayArea,Pay 要生成如下形式报表: Org1,A1,100,4 Org1,A2,100,4 Org1,A3,100,4 Org1小计,XX,XX,XX Org2,B1,100,4 .... 合计, XX ,XX SQL: select OrgName DD,STAFFNAME,PayArea, Pay,OrgName as EE from Table1 as t1 union select OrgName || '小计' DD,'',sum(PayArea),sum(Pay),OrgName || '_' EE from Table1 as t2 group by DEPT_ID union Select '合计' as DD,'',sum(PayArea),sum(Pay),'ZZZZZZZZ' as EE from Table1 order by EE 其中的OrgName||'_' 是为了取得一个比下一个不同的OraName大一些的值,以便让小计这条数据排在适当的位置,如 Org1小计要排在Org1和Org2之间,所以要选一个在数据库中字符排序号小的字符,这里以"_"表示。'ZZZZZZZZ'则 是为了把合计记录排在最后,所以要选一串在数据库中字符排序最大的字符构成的串,这里只是用'Z'来表示。 用ee 排序,但合计中 'ZZZZZZZZ' EE ,如果OrgName是汉字的话,那么排序后,合计将会变为第一行的,英文字母总是显示在汉字前面, 这样就达不到合计显示在最后一行的目的了,如果将合计中'ZZZZZZZZ' EE 变为'做做做做做做做做' EE 这样就能使 合计排在最后一行,因为'做'字是字典中最后一个字 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

oracle行转列

具体Sql语句怎么写 比如这个例子,但是科目不固定,是动态的 Create table test (name char(10),km char(10),cj Number) insert into test values('张三','语文',80) insert into test values('张三','数学',86) insert into test values('张三','英语',75) insert into test values('李四','语文',78) insert into test values('李四','数学',85) insert into test values('李四','英语',78) commit; 怎样实现成这样: name 语文数学英语 李四78 85 83 张三80 86 75 Top 3 楼chenyiwei(无心快语)回复于2004-11-0 4 11:31:56 得分0 一个比较笨的办法: select name, sum(decode(km,'语文',cj,0) 语文, sum(decode(km,'数学',cj,0) 数学, sum(decode(km,'英语',cj,0) 英语 from test group by name Top 4 楼rwpublic(rwpublic)回复于2004-11-04 11:44:01 得分0 如何实现行列转换 [A]1、固定列数的行列转换 如 student subject grade --------------------------- student1 语文80 student1 数学70 student1 英语60 student2 语文90 student2 数学80 student2 英语100 …… 转换为 语文数学英语 student1 80 70 60 student2 90 80 100 ……

用ORACLE分析函数实现行列转换

用ORACLE分析函数实现行列转换 黄莉玉素甫·艾白都拉 (新疆师范大学数理信息学院,新疆830054) 摘要对数据库中的数据用SQL实现行列转换,不但需要编写复杂的程序代码,还需要编写存储过程。若引入ORACLE中的分析函数则会使该过程简便很多。首先找出表中所有关键字的属性个数的最大值,设为n,其次为每个关键字新添加n列,并用分析函数查询关键字的属性所处列的位置,然后将每个关键字的多行属性转换成多列属性,最后把生成的多个新列拼成一个串形成一列,从而实现行列转换。 关键字Oracle数据库;分析函数;行列转换 1引言 分析函数的设计目的是为了解决诸如“累计计算”等问题。虽然大部分的问题都可以用PL/SQL解决,但是性能并不理想,首先查询本身并不容易编写,其次有些很难在SQL中直接做的查询但实际上是很普通的操作,比如实现数据表中行列传换。这样的问题在SQL中做查询就很困难。在分析函数出现以前,我们必须使用自联查询或者子查询甚至复杂的存储过程实现的语句,现在只要一条简单的SQL语句就可以实现了,而且在执行效率方面也有相当大的提高。本文将以一个实例来描述如何采用分析函数实现数据中的行列互换。 2原理 2.1分析函数的格式及语法 分析函数是在一个记录行分组的基础上计算它们的总值。行的分组被称窗口,并通过分析语句定义。对于每记录行,定义了一个“滑动”窗口。该窗口确定“当前行”计算的范围。窗口的大小可由各行的实际编号或由时间等逻辑间隔确定。分析函数以如下形式开头: Analytic-Function(,...)

OVER ()(1)Analytic-Function:分析函数的名称,Oracle10gR2带的内置分析函数有多个,包括:AVG、CORR、COVAR_POP、COVAR_SAMP、COUNT、LAG、LAST、LEAD、MAX、MIN、RANK、SUM等;对于用户自定义的分析函数,分析函数名称需要满足标识符规则。 (2)Arguments:参数,分析函数通常有0到3个参数,参数可以是任何数字类型或是可以隐式转换为数字类型的数据类型。对于用户自定义的参数,可以根据实际情况使用。 (3)OVER:是分析函数就必须使用的关键字,对于既可作为聚集函数又可作为分析函数的函数,Oracle无法识别,必须用over来标识此函数为分析函数。(4)Query-Partition-Clause:查询分组子句,根据划分表达式设置的规则,PARTITION BY将一个结果逻辑分成N个分组划分表达式。分析函数独立应用于各个分组,并在应用时重置。 (5)Order-By-Clause:(按…排序分组),是排序子句,根据一个或多个排序表达式对分组进行排序。 (6)Windowing-Clause窗口生成语句:窗口生成语句用以定义滑动或固定数据窗口,分析函数在分组内进行分析。该语句能够对分组中任意定义的滑动或固定窗口进行计算。 2.2实例原理介绍 本实例是将具有相同关键字的多条记录中的某一不同列合并成一列,例如在一个临时表中包含有用户的编号、电话号码、产品名称、所在营业区以及相关业务名称5个字段,而每个用户的业务可能有多项,这样创建数据表将会造成冗余,现在要想办法将表中编号、电话号码、产品名称、所在营业区四个字段相同的用户的相关业务属性合并成一列解决冗余问题,使用SQL语句会比较困难,甚至需要一定的存储过程。使用Orcale中的分析函数来实现这样的行列转换就比较简单方便了。 3实例 1)创建临时表 Drop Table temp; Create Table temp

Oracle经验分享-多行合并一行、行列对调

Oracle 多行合并一行方法 NOTE:特别声明一下内容转自网络 https://www.doczj.com/doc/292837795.html,/html/2008/how_to_do_string_aggregate_on_oracle. html 一、实现要求 初始化表: create table t(i int,a varchar(10),d varchar(100)); insert into t(i,a,d) values('1','b','2008-03-27 10:55:42'); insert into t(i,a,d) values('1','a','2008-03-27 10:55:46'); insert into t(i,a,d) values('1','d','2008-03-27 10:55:30'); insert into t(i,a,d) values('2','z','2008-03-27 10:55:55'); insert into t(i,a,d) values('2','t','2008-03-27 10:55:59'); 查询: 假如有如下表,其中各个i值对应的行数是不定的 SQL> select * from t; I A D ---------- ---------- ------------------- 1 b 2008-03-27 10:55:42 1 a 2008-03-27 10:55:46 1 d 2008-03-27 10:55:30 2 z 2008-03-27 10:55:55 2 t 2008-03-27 10:55:59 实现要求: 要获得如下结果,注意字符串需要按照D列的时间排序: 1 d,b,a 2 z,t 二、解决方案 这是一个比较典型的行列转换,有好几种实现方法 1.自定义函数实现 Sql代码 1.create or replace function my_concat(n number) 2.return varchar2 3.is 4.type typ_cursor is ref cursor; 5.v_cursor typ_cursor; 6.v_temp varchar2(10); 7.v_result varchar2(4000):= '';

Oracle11g最佳视频教程(王二暖Oracle11g教室10年经验毫无保留)

Oracle11g最佳视频教程(王二暖Oracle11g教室10年经 验毫无保留) Oracle11g最佳培训教程(王二暖Oracle11g教室10年经验毫无保留) 北风网学习地址: 王二暖Oracle11g教室系列课程,为讲师10年经验,毫无保留的讲授,课程分为31部分,涉及内容包括ORACLE11g的体系结构、ORACLE中的特有SQL语法、SQL语法深入分析、分区与索引、视图,触发器,函数,存储过程,游标等技术的使用、大对象的存取技巧、数据备份与移植、物化视图等重要内容。该课程深浅程度、时间完全透明,知识点全面,覆盖11g使用和初步管理中的所有的重要内容。课程内容完全按照:例子+实验题目的模式。知识点解读极其细致,语言通俗易懂。 培训课程内容简介: ORACLE11g的体系结构、ORACLE中的特有SQL语法、SQL语法深入分析、分区与索引、视图,触发器,函数,存储过程,游标等技术的使用、大对象的存取技巧、数据备份与移植、物化视图等重要内容(完整的内容介绍,参考“开篇部分本视频课程简介”)。 该培训课程的内容、深浅程度、时间完全透明,可以观看“开篇部分本视频课程简介”的详细介绍,可以看到具体培训内容、培训时间(精确到分钟)、并可试听部分内容。该培训课程全套31部分,占用3.32G。是极实用、全面、讲解细致的Oracle11g的课程。 本套培训课程特点: 实用性是第一要素 知识点全面,覆盖11g使用和初步管理中的所有的重要内容 课程内容完全按照:例子+实验题目的模式

该培训课程的内容、课程的深浅程度、每部分占用的时间、课程讲解的具体内容先告知学员,这在培训界中绝无仅有 同类产品中,保证质量上乘,可以和任何其他培训进行对比 知识点解读极其细致,语言通俗易懂 性价比超高 “王二暖Oracle11g教室”培训课程的具体课程目录如下: 第1部分 Oracle11g简介 1.1 Oracle的发展 1.2 Oracle的主要产品 1.3 为什么要学习Oracle11g 1.4 Oracle11g简介 1.5 Oracle11g的认证 1.6 Oracle11g的安装(for Windows) 1.7 Oracle11g的服务 1.8 Oracle11g的卸载 1.9 访问Oracle11g的工具 1.10 Oracle11g常用的SQL*Plus命令 1.11 Oracle11g的网络配置 第2.1部分 Oracle11g的基本SQL语句和函数 2.1.1 Oracle的数据类型 2.1.2 数据定义语言 2.1.3 数据操纵语言 2.1.4 SELECT命令详解

oracle中decode函数实现行转列

oracle decode 函数实现行转列 ----创建测试表 create table student_score( name varchar2(20), subject varchar2(20), score number(4,1) ); -----插入测试数据 insert into student_score (name,subject,score)values('张三','语文',78); insert into student_score (name,subject,score)values('张三','数学',88); insert into student_score (name,subject,score)values('张三','英语',98); insert into student_score (name,subject,score)values('李四','语文',89); insert into student_score (name,subject,score)values('李四','数学',76);

insert into student_score (name,subject,score)values('李四','英语',90); insert into student_score (name,subject,score)values('王五','语文',99); insert into student_score (name,subject,score)values('王五','数学',66); insert into student_score (name,subject,score)values('王五','英语',91); -----decode行转列 select name"姓名", sum(decode(subject, '语文', nvl(score, 0), 0)) "语文", sum(decode(subject, '数学', nvl(score, 0), 0)) "数学", sum(decode(subject, '英语', nvl(score, 0), 0)) "英语" from student_score group by name; ------ case when 行转列 select name"姓名", sum(case when subject='语文' then nvl(score,0)

相关主题
文本预览
相关文档 最新文档