• 售前

  • 售后

热门帖子
入门百科

深入sql oracle递归查询

[复制链接]
淡淡如菊795 显示全部楼层 发表于 2021-10-26 13:39:29 |阅读模式 打印 上一主题 下一主题
☆ 获取数据库所有表名,表的所有列名
   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

帖子地址: 

回复

使用道具 举报

分享
推广
火星云矿 | 预约S19Pro,享500抵1000!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

草根技术分享(草根吧)是全球知名中文IT技术交流平台,创建于2021年,包含原创博客、精品问答、职业培训、技术社区、资源下载等产品服务,提供原创、优质、完整内容的专业IT技术开发社区。
  • 官方手机版

  • 微信公众号

  • 商务合作