几个行列转换的实用小例子(r4笔记第2天)
起行列转换,大家是既熟悉又陌生,在oracle 10g版本之前如果要做行列转换,都基本得使用decode来完成,在11g中情况有了改观,可以直接使用pivot特性来完成。这种方式相比decode来说要更加简洁清晰。
我们来举两个例子来说明一下。
-->session状态的监控
对于数据库中的session状态监控可以作为系统运维工作的一部分,一旦发现session异常就可以很快定位出可能是哪些类型的问题。
我们创建一个临时表来替代v$session来说明。
create table session_test as select *from v$session;
select username,count(*)cnt,status from session_test group by username,status;
我们得到的当前session情况如下:
USERNAME CNT STATUS
------------------------------ ---------- --------
N1 1 ACTIVE
MIG 1 INACTIVE
25 ACTIVE
如果用户很多,同一个用户下存在多个session(ACTIVE或者INACTIVE)。
查看的时候就不是很清晰。如果能够行列转换一下,显示成下面的格式就好了。
username active inactive sniped.....
xxxx 1 2 0
xxxx 2 0 0
可以使用pivot来实现。
select *from
(
select username,status from session_test
)
pivot
(
count(status)
for status in ('ACTIVE','INACTIVE','KILLED','SNIPED','CACHED')
)
order by username nulls first;
输出结果如下:
USERNAME 'ACTIVE' 'INACTIVE' 'KILLED' 'SNIPED' 'CACHED'
------------------------------ ---------- ---------- ---------- ---------- ----------
25 0 0 0 0
MIG 0 1 0 0 0
N1 1 0 0 0 0
这种方式相比以前的decode方式要好很多,而且要清晰。不过有一点,这种方式中,for status in ('ACTIVE','INACTIVE','KILLED','SNIPED','CACHED')的部分是需要预先知道的。在这个例子中不是问题,因为状态很有限,就那几个,可以通过官方文档中的v$session字段解释得到。session的状态就下面5种。
STATUS |
VARCHAR2(8) |
Status of the session:ACTIVE - Session currently executing SQLINACTIVEKILLED - Session marked to be killedCACHED - Session temporarily cached for use by Oracle*XASNIPED - Session inactive, waiting on the client |
---|
- ACTIVE - Session currently executing SQL
- INACTIVE
- KILLED - Session marked to be killed
- CACHED - Session temporarily cached for use by Oracle*XA
- SNIPED - Session inactive, waiting on the client
-->查看schema下的object_type 如果我们查看一个数据库中数据的整体分布情况,想知道每个schema下的object分布情况,比如存在多少个表,多少索引,同义词等,这些对于很多潜在的问题分析都是很有帮助的。如果同样结构的环境中丢失了某一个同义词,可能需要很长的时间才能发现问题,如果我们简单比较一下object的分布情况,就可以很容易的分析出问题来。 我们采用all_objects做为数据来源,创建一个临时表来处理。
create table obj_test as select *from all_objects;
select owner,object_type,count(*) from obj_test group by owner,object_type order by owner;
得到的结果如下:
SCOTT TABLE 5
SYS CLUSTER 10
SYS CONSUMER GROUP 2
SYS CONTEXT 3
SYS DESTINATION 2
SYS DIRECTORY 10
SYS EDITION 1
SYS EVALUATION CONTEXT 10
OWNER OBJECT_TYPE COUNT(*)
------------------------------ ------------------- ----------
SYS FUNCTION 87
SYS INDEX 1018
SYS INDEX PARTITION 121
SYS JOB 9
SYS JOB CLASS 13
SYS LIBRARY 142
SYS OPERATOR 7
SYS PACKAGE 579
SYS PACKAGE BODY 556
SYS PROCEDURE 93
SYS PROGRAM 19
SYS RULE 1
SYS RULE SET 13
SYS SCHEDULE 3
SYS SCHEDULER GROUP 4
SYS SEQUENCE 116
SYS SYNONYM 6
SYS TABLE 989
SYS TABLE PARTITION 121
SYS TABLE SUBPARTITION 32
SYS TRIGGER 4
可以很清楚地看到每个用户下的object的分布情况,但是这样看很不清晰,而且我们可能并不需要知道所有的object_type,我们只是想得到一些基本的object type的情况。 可以采用如下的方式来做。
select *from
(
select owner,object_type from obj_test
)
pivot
(
count(*)
for object_type in ('TABLE','INDEX','SYNONYM','PROCEDURE','FUNCTION','PACKAGE','VIEW')
)
order by owner;
OWNER 'TABLE' 'INDEX' 'SYNONYM' 'PROCEDURE' 'FUNCTION' 'PACKAGE' 'VIEW'
------------------------------ ---------- ---------- ---------- ----------- ---------- ---------- ----------
APPQOSSYS 4 0 1 0 0 0 0
APP_CONN 0 0 4 0 0 0 0
DBSNMP 20 10 1 1 0 3 7
JEANRON 1 0 0 0 0 0 0
MIG 0 0 1 0 0 0 0
N1 46 10 0 5 3 3 0
ORACLE_OCM 0 0 0 0 0 3 0
OUTLN 3 4 0 1 0 0 0
PUBLIC 0 0 3281 0 0 0 0
SCOTT 5 2 0 0 0 0 0
SYS 989 1018 6 93 87 579 3730
SYSTEM 157 215 8 1 0 1 14
TABOWNER 1 0 0 0 0 0 0
上面这种方式要清晰地多,而且更有针对性。 当然关于行列转换,model子句也是很实用的,准备在后续的博客中继续分享。我们抛砖引玉,用一个在论坛中比较有意思的例子来说明一下。 大家能够猜出下面的sql语句运行的结果吗?稍微停顿一下再看答案。
select c from
(select * from
(select 'oracle' cc, level no from dual connect by level <= length('oracle'))
model return updated rows
dimension by (no)
measures (cc c, no n)
rules (
c[any] = substr(c[cv()],n[cv()],1)
));
C
------
o
r
a
c
l
e
6 rows selected.
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- c++实例之通讯录管理系统之显示联系人功能(三)
- c++实例之通讯录管理系统之删除联系人功能(四)
- springboot检索之Elasticsearch简介
- c++实例之通讯录管理系统之查找联系人功能(五)
- 【python-leetcode424-滑动窗口法】替换后的最长重复字符
- c++实例之通讯录管理系统之修改联系人功能(六)
- 解决arxiv.org打开pdf缓慢问题
- c++实例之通讯录管理系统之清空联系人功能(七)
- springboot任务之定时任务
- springboot检索之整合elasticsearch并使用jest操作
- springboot任务之邮件任务
- springboot安全之整合spring security实现(只有登录才有权限、不同用户显示不同内容、记住我)
- springboot任务之异步任务
- springboot缓存之@Cacheable中常用参数
- springboot开发之添加员工