查阅代码整理(五)之oracle 特殊函数用法(行转列,树查询等)

今天在修改代码时发现一个公司未知人员写的sql,然后学习了一下午,贴出供自己查询学习。

 

部分脚本:

(case when dmid is null then '无' else

( select to_char(wm_concat(dm.dmmc)) dmmc from gg_test dm where dm.id in( select dmid from (

select id, regexp_substr(dmid , '[^,]+', 1, level) dmid

from jd_test

connect by level <= regexp_count(dmid , ',') + 1

and id = prior id

and prior dbms_random.value is not null

) end )

 

其中使用了case when , to_char, wm_concat, regexp_substr, level, regexp_count, connect by prior, dbms_random.value 其中有的地方很理解后感觉学无止境呀。

直接上大招。

脚本中:

and id = prior id

and prior dbms_random.value is not null

问了一大圈许多人都不知道什么原因,或者只知道个大概,查了好久才明白了此处。

原贴:原贴15楼答复

15楼做出解答

 

简单而言:

使用prior id=id来identify同一行,用dbms_random.values来返回不同值以欺骗Oracle从而规避报错。

CONNECT BY它相当于一个递归的自连接,不断地把每层的连接结果叠加到结果集中。两层之间的连接条件和递归出口都写在CONNECT BY中。在这里我们的数据并无父子关系,只是要让同一行数据重复出现,因此我们的连接的条件只用到了表的主键id=PRIOR id, 此外再用LEVEL控制层数作为递归出口。但ORACLE有个检查,如果你有前后连接条件(id=PRIOR id),但是同一行数据再次出现,它就会报一个错:
ERROR:
ORA-01436: CONNECT BY loop in user data
为了欺骗它,这里用了一个PRIOR DBMS_RANDOM.VALUE, 因为DBMS_RANDOM.VALUE每次调用都返回不同结果,所以它认为两行数据不一样,所以不报错了。

 

其他函数解读:

1 case when else end

 

类似我们的if ...else ,判断语句

语法如下:

CASE expr WHEN expr1 THEN return_expr1

         [WHEN expr2 THEN return_expr2

          ...

          WHEN exprn THEN return_exprn

          ELSE else_expr]

END

 

第二种延伸用法:

CASE

       WHEN  expr1 THEN return_expr1

       [WHEN expr2 THEN return_expr2

       ....

       WHEN exprn THEN return_exprn

       ELSE else_expr]

END

2 decode函数

 

decode(条件,值1,返回值1,值2,返回值2,...值n,返回值n,缺省值)

语法:

DECODE(col|expression, search1, result1

[, search2, result2,...,]

...

 [, searchn, resultn,...,]

[, default])

如果 条件=值1,那么显示结果1

如果 条件=值2,那么显示结果2

....

如果 条件=值n,那么显示结果n

都不符合,则显示缺省值

注:sign()函数根据参数1的值是0、正数还是负数,分别返回0、1、-1

 

3 start with  connect by prior 递归查询

 

用于B树结构类型的数据递归查询,给出B树结构类型中的任意一个结点,遍历其最终父结点或者子结点

SELECT ... FROM+ 表名

START WITH+ 条件1

CONNECT BY PRIOR+ 条件2

WHERE + 条件3

条件1:是根节点的限定语句,当然可以放宽限定条件,以取得多个根节点,也就是多棵树;在连接关系中,除了可以使用列明外,还允许使用列表达式。

START WITH 子句为可选项,用来标识哪个节点作为查找树形结构的根节点。若该子句省略,则表示所有满足查询条件的行作为根节点。

条件2:是连接条件,其中用PRIOR表示上一条记录,例如CONNECT BY PRIOR STUDENT_ID = GRADE_ID,意思就是上一条记录的STUDENT_ID是本条记录的GRADE_ID,即本记录的父亲是上一条记录。CONNECT BY子句说明每行数据将是按照层次顺序检索,并规定将表中的数据连入树形结构的关系中。

PRIOR运算符必须放置在连接关系的2列中某一个的前面。对于节点间的父子关系,PRIOR运算符在一侧表示父节点,在另一侧表示子节点,从而确定查

找树结构的顺序是自顶向下,还是自底向上。

条件3:是过滤条件,用于对返回的记录进行过滤。

此段原博客: https://www.pianshen.com/article/81771258372/

4 REGEXP_SUBSTR函数

 

格式如下:

REGEXP_SUBSTR(srcstr, pattern, position, occurrence, modifier)

srcstr :需要进行正则处理的字符串

pattern :进行匹配的正则表达式

position :起始位置,从第几个字符开始正则表达式匹配(默认为1)

occurrence :标识第几个匹配组,默认为1

modifier :模式('i'不区分大小写进行检索;'c'区分大小写进行检索。默认为'c'。)

5  EGEXP_COUNT函数

 

统计字符串出现的次数。

6 wm_concat函数

 

是一个聚合函数,其作用是将一列数据转换成一行,也就是我们常用的行转列。

这里有个坑,有时wm_concat会报错,好像是格式不正确,这个时候可以使用to_char()。

该函数是一个undocument函数,所以不推荐大家使用这个函数。因为在后续的版本中还提不提供这个函数都不好说呢。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值