深入sql oracle递归查询

所属分类: 数据库 / oracle 阅读数: 279
收藏 0 赞 0 分享
☆ 获取数据库所有表名,表的所有列名
   select name from sysobjects where xtype='u'
   select name from syscolumns where id=(select max(id) from sysobjects where xtype='u' and name='表名')

☆ 递归查询数据
Sql语句里的递归查询 SqlServer2005和Oracle 两个版本
以前使用Oracle,觉得它的递归查询很好用,就研究了一下SqlServer,发现它也支持在Sql里递归查询
举例说明:
SqlServer2005版本的Sql如下:
比如一个表,有id和pId字段,id是主键,pid表示它的上级节点,表结构和数据:
CREATE TABLE [aaa](
 [id] [int] NULL,
 [pid] [int] NULL,
 [name] [nchar](10)
)
GO
INSERT INTO aaa VALUES(1,0,'a')
INSERT INTO aaa VALUES(2,0,'b')
INSERT INTO aaa VALUES(3,1,'c')
INSERT INTO aaa VALUES(4,1,'d')
INSERT INTO aaa VALUES(5,2,'e')
INSERT INTO aaa VALUES(6,3,'f')
INSERT INTO aaa VALUES(7,3,'g')
INSERT INTO aaa VALUES(8,4,'h')
GO
--下面的Sql是查询出1结点的所有子结点
with my1 as(select * from aaa where id = 1
 union all select aaa.* from my1, aaa where my1.id = aaa.pid
)
select * from my1 --结果包含1这条记录,如果不想包含,可以在最后加上:where id <> 1
--下面的Sql是查询出8结点的所有父结点
with my1 as(select * from aaa where id = 8
 union all select aaa.* from my1, aaa where my1.pid = aaa.id
)
select * from my1;
--下面是递归删除1结点和所有子结点的语句:
with my1 as(select * from aaa where id = 1
   union all select aaa.* from my1, aaa where my1.id = aaa.pid
)
delete from aaa where exists (select id from my1 where my1.id = aaa.id)
Oracle版本的Sql如下:
比如一个表,有id和pId字段,id是主键,pid表示它的上级节点,表结构和数据请参考SqlServer2005的,Sql如下:
--下面的Sql是查询出1结点的所有子结点
 SELECT * FROM aaa
  START WITH id = 1
CONNECT BY pid = PRIOR id
--下面的Sql是查询出8结点的所有父结点
 SELECT * FROM aaa
  START WITH id = 8
CONNECT BY PRIOR pid = id
今天帮别人做了一个有点意思的sql,也是用递归实现,具体如下:
假设有个销售表如下:
CREATE TABLE [tb](
    [qj] [int] NULL,    -- 月份,本测试假设从1月份开始,并且数据都是连续的月份,中间没有隔断
    [je] [int] NULL,    -- 本月销售实际金额
    [rwe] [int] NULL,    -- 本月销售任务额
    [fld] [float] NULL    -- 本月金额大于任务额时的返利点,返利额为je*fld
) ON [PRIMARY]
现在要求计算每个月的返利金额,规则如下:
1月份销售金额大于任务额  返利额=金额*返利点
2月份销售金额大于任务额  返利额=(金额-1月份返利额)*返利点
3月份销售金额大于任务额  返利额=(金额-1,2月份返利额)*返利点
以后月份依次类推,销售额小于任务额时,返利为0
具体的Sql如下:
复制代码 代码如下:

WITH my1 AS (
                SELECT *,
                       CASE
                            WHEN je > rwe THEN (je * fld)
                            ELSE 0
                       END fle,
                       CAST(0 AS FLOAT) tmp
                FROM   tb
                WHERE  qj = 1
                UNION ALL
                SELECT tb.*,
                       CASE
                            WHEN tb.je > tb.rwe THEN (tb.je - my1.fle -my1.tmp)
                                 * tb.fld
                            ELSE 0
                       END fle,
                       my1.fle + my1.tmp tmp -- 用于累加前面月份的返利
                FROM   my1,
                       tb
                WHERE  tb.qj = my1.qj + 1
            )
SELECT *
FROM   my1

SQLserver2008使用表达式递归查询
--由父项递归下级
with cte(id,parentid,text)
as
(--父项
select id,parentid,text from treeview where parentid = 450
union all
--递归结果集中的下级
select t.id,t.parentid,t.text from treeview as t
inner join cte as c on t.parentid = c.id
)
select id,parentid,text from cte
---------------------
--由子级递归父项
with cte(id,parentid,text)
as
(--下级父项
select id,parentid,text from treeview where id = 450
union all
--递归结果集中的父项
select t.id,t.parentid,t.text from treeview as t
inner join cte as c on t.id = c.parentid
)
select id,parentid,text from cte
更多精彩内容其他人还在看

Oracle 子程序参数模式,IN,OUT,NOCOPY

Oracle 子程序参数模式主要有IN,OUT,NOCOPY,IN和OUT可以组合,OUT和NOCOPY也可以组合使用.
收藏 0 赞 0 分享

Oracle 存储过程加密方法

Oracle 存储过程加密方法,需要的朋友可以参考下。
收藏 0 赞 0 分享

oracle 多个字符替换实现

CSDN上的一个网友,需要一个sql语句的解决方案需求是这样的求写oracle多个字符替换(有测试数据)
收藏 0 赞 0 分享

Oracle 存储过程教程

一个简单的oracle分页存储过程的实现和调用。在看了众多的分页存储过程以后发现都是针对sqlserver的,而没有oracle的,因此想写一个关于oracle的存储过程,因为我用到的数据库是oracle。
收藏 0 赞 0 分享

oracle 更改数据库名的方法

这两天一朋友问如何更改数据库名,于是做个测试,简单记录下,以便说明问题。
收藏 0 赞 0 分享

Oracle 分析函数RANK(),ROW_NUMBER(),LAG()等的使用方法

Oracle分析函数RANK(),ROW_NUMBER(),LAG()等的使用方法,需要的朋友可以参考下。
收藏 0 赞 0 分享

Oracle字符集修改查看方法

Oracle字符集修改查看方法,需要的朋友可以参考下。
收藏 0 赞 0 分享

一些实用的sql语句

一些实用的sql,需要的朋友可以参考下。
收藏 0 赞 0 分享

Oracle中sys和system的区别小结

SYS用户具有DBA权限,并且拥有SYS模式,只能通过SYSDBA登陆数据库。是Oracle数据库中权限最高的帐号 SYSTEM具有DBA权限。但没有SYSDBA权限。平常一般用该帐号管理数据库就可以了。
收藏 0 赞 0 分享

oracle 存储过程和触发器复制数据

oracle 存储过程和触发器复制数据的代码,需要的朋友可以参考下。
收藏 0 赞 0 分享
查看更多