Discuz教程网

oracle分析析function --NB

[复制链接]
authicon 飞飞 发表于 2010-10-26 03:17:54 | 显示全部楼层 |阅读模式

本帖最后由 yobyin 于 2010-06-22 22:08 编辑
搞几个变态的报表...把多行转成一行,按一个column的排序后取前30%名
多行转一行
CREATE TABLE t_row_str(
ID INT,
col VARCHAR2(10));
INSERT INTO t_row_str VALUES(1,'a');
INSERT INTO t_row_str VALUES(1,'b');
INSERT INTO t_row_str VALUES(1,'c');
INSERT INTO t_row_str VALUES(2,'a');
INSERT INTO t_row_str VALUES(2,'d');
INSERT INTO t_row_str VALUES(2,'e');
INSERT INTO t_row_str VALUES(3,'c');
COMMIT;
SELECT * FROM t_row_str;
5.1
MAX + DECODE
适用范围:8i,9i,10g及以后版本
SELECT id,
MAX(decode(rn, 1, col, NULL)) ||
MAX(decode(rn, 2, ',' || col, NULL)) ||
MAX(decode(rn, 3, ',' || col, NULL)) str
FROM (SELECT id,
col,
row_number() over(PARTITION BY id ORDER BY col) AS rn
FROM t_row_str) t
GROUP BY id
ORDER BY 1;
5.2
ROW_NUMBER + LEAD
适用范围:8i,9i,10g及以后版本
SELECT id, str
FROM (SELECT id,
row_number() over(PARTITION BY id ORDER BY col) AS rn,
col || lead(',' || col, 1) over(PARTITION BY id ORDER BY col) ||
lead(',' || col, 2) over(PARTITION BY id ORDER BY col) ||
lead(',' || col, 3) over(PARTITION BY id ORDER BY col) AS str
FROM t_row_str)
WHERE rn = 1
ORDER BY 1;
5.3
MODEL
适用范围:10g及以后版本
SELECT id, substr(str, 2) str FROM t_row_str
MODEL
RETURN UPDATED ROWS
PARTITION BY(ID)
DIMENSION BY(row_number() over(PARTITION BY ID ORDER BY col) AS rn)
MEASURES (CAST(col 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;
5.4
SYS_CONNECT_BY_PATH
适用范围:8i,9i,10g及以后版本
SELECT t.id id, MAX(substr(sys_connect_by_path(t.col, ','), 2)) str
FROM (SELECT id, col, row_number() over(PARTITION BY id ORDER BY col) rn
FROM t_row_str) t
START WITH rn = 1
CONNECT BY rn = PRIOR rn + 1
AND id = PRIOR id
GROUP BY t.id;
适用范围:10g及以后版本
SELECT t.id id, substr(sys_connect_by_path(t.col, ','), 2) str
FROM (SELECT id, col, row_number() over(PARTITION BY id ORDER BY col) rn
FROM t_row_str) t
WHERE connect_by_isleaf = 1
START WITH rn = 1
CONNECT BY rn = PRIOR rn + 1
AND id = PRIOR id;
5.5
WMSYS.WM_CONCAT
适用范围:10g及以后版本
这个函数预定义按','分隔字符串,若要用其他符号分隔可以用,replace将','替换。
SELECT id, REPLACE(wmsys.wm_concat(col), ',', '/') str
FROM t_row_str
GROUP BY id;
------------------取按列排名的指定记录
select * from (
  select t.*,cume_dist() over(order by t.score) cume_dist
  from testtable t)
where  cume_dist>=0.1 and cume_dist<=0.5 ;
oracle 分析function nb
select * from (
  select t.*,cume_dist() over(order by t.score) cume_dist
  from testtable t)
where  cume_dist>=0.1 and cume_dist<=0.5 ;



上一篇:用HP MC/SG做群集,HA和RAC有什么不同?
下一篇:一本好书,不敢独享Oracle.Database.10g.Performance.Tuning.Tips.and.Techniques
authicon yobyin 发表于 2010-10-26 03:40:19 | 显示全部楼层

分析函数:
ntile
功能描述:将一个组分为"表达式"的散列表示,比如,假设表达式=4,则给组中的每一行分配一个数(从1到4),假设组中有20行,则给前5行分配1,给下5行分配2等等。假设组的基数不能由表达式值平均分开,则对这些行进行分配时,组中就没有任何percentile的行数比其它percentile的行数超过一行,最低的percentile是那些拥有额外行的percentile。比如,若表达式=4,行数=21,则percentile=1的有6行,percentile=2的有5行等等。
sql@kokooa>select id,value,ntile(4) over (order by value) as
2 quartile from test017;
        ID      VALUE   QUARTILE
---------- ---------- ----------
         1        123          1
         3        345          1
         4        456         2
         5        567          3
         6        567          4
PERCENT_RANK
功能描述:和CUME_DIST(累积分配)函数类似,对于一个组中给定的行来说,在计算那行的序号时,先减1,然后除以n-1(n为组中所有的行数)。该函数总是返回0~1(包括1)之间的数。RANK函数对于等值的返回序列值是一样的
sql@kokooa>select id,value,percent_rank()over(order by id) as pr from test017;
        ID      VALUE         PR
---------- ---------- ----------
         1        123          0
         3        345        .25
         4        456         .5
         5        567        .75
         6        567         1
假设有重复元素呢?
sql@kokooa>select id,value,percent_rank()over(order by id) as pr from test017;
        ID      VALUE         PR
---------- ---------- ----------
         1        123          0
         1        234          0
         3        345         .4
        4        456         .6
         5        567         .8
         6        567          1
其中开头两行id重复。
sql@kokooa>select id,value,percent_rank()over(order by id) as pr from test017;
        ID      VALUE         PR
---------- ---------- ----------
         1        123          0
         2        234         .2
         3        345         .4
         3        456         .4
         5        567         .8
         6        567          1
sql@kokooa>select id,value,percent_rank()over(order by id) as pr from test017;
        ID      VALUE         PR
---------- ---------- ----------
         3        123          0
         3        234          0
         3        345          0
         3        456          0
         3        567          0
         6        567          1
继续测:
sql@kokooa>select id,value,percent_rank()over(order by id) as pr from test017;
        ID      VALUE         PR
---------- ---------- ----------
         3        123          0
         3        234          0
         3        345          0
         3        456          0
         5        567         .8
         6        567          1
应该是(5-1)/5=0.8 (6-1)/5=1;
Cume_dist
sql@kokooa>select id,value,cume_dist()over(order by id) as pr from test017;
        ID      VALUE         PR
---------- ---------- ----------
         3        123         .5
       3        234         .5
         3        345         .5
         5        456 .833333333
         5        567 .833333333
         6        567          1
应该是行数/总行数。假设有重复的,如上:则前3行是3/6 接着2行是5/6。被除数以重复行的最后一行的行数为准。
authicon evaspring 发表于 2010-10-26 04:11:46 | 显示全部楼层

:em17: 华为上研中心 就搞这个啊 ·
authicon bigapple2008 发表于 2010-10-26 04:37:54 | 显示全部楼层

为啥华为杭州没搞Oracle的
authicon yobyin 发表于 2010-10-26 05:22:18 | 显示全部楼层

select * from
(select t.* ,row_number() over (partition by groupid  order by score) rm  from  testtable t ) a where a.rm=1   这个去重的
authicon dingning239 发表于 2010-10-26 06:02:15 | 显示全部楼层

分析函数非常方便地简化了做报表的复杂度,向楼主学习
authicon yobyin 发表于 2010-10-26 06:49:57 | 显示全部楼层

select regexp_substr('[10000]/[100]*{100}', '[[:digit:]]{3,5}',1,1) from dual;
select regexp_substr('[10000]+[100]', '[[:digit:]]{3,5}',1,2) from dual;
authicon yobyin 发表于 2010-10-26 07:27:18 | 显示全部楼层

select regexp_substr('[10000]+[100]', '[[:digit:]]{3,5}',1,1) from dual;
select regexp_substr('[10000]+[100]', '[[:digit:]]{3,5}',1,2) from dual;
select regexp_substr('[10000]+[100]', '[[:digit:]]+',1,1) A from dual;
select regexp_substr('[10000]+[100]', '[[:digit:]]+',1,2) B from dual;
authicon yobyin 发表于 2010-10-26 08:00:09 | 显示全部楼层

正则表达式
authicon dream_land 发表于 2010-10-26 08:16:17 | 显示全部楼层

总结的很好,对弄报表的人很有用
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

1314学习网 ( 浙ICP备10214163号 )

GMT+8, 2025-5-2 18:36

Powered by Discuz! X3.4

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表