SQLserver, Oracle 限制层数 递归查询和反向查询父记录

1 篇文章 0 订阅
1 篇文章 0 订阅

以前使用Oracle,觉得它的递归查询很好用,就研究了一下SqlServer,发现它也支持在Sql里递归查询
举例说明:
SqlServer2008版本的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

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SQL Server递归查询是一种在关系型数据库中使用递归算法进行数据查询的方法。它可以用于处理具有层次结构的数据,例如组织结构、树形结构等。在SQL Server中,递归查询可以通过使用公共表表达式(CTE)和递归联接来实现。 递归查询的基本思想是通过递归联接将一个表与自身连接,从而实现对层次结构数据的遍历和查询。在递归查询中,需要定义一个递归部分和一个终止条件。 下面是一个示例,演示如何使用递归查询SQL Server查询组织结构的层级关系: ```sql -- 创建一个示例表 CREATE TABLE Organization ( ID INT, Name VARCHAR(50), ParentID INT ); -- 插入示例数据 INSERT INTO Organization (ID, Name, ParentID) VALUES (1, '公司', NULL), (2, '部门A', 1), (3, '部门B', 1), (4, '小组A1', 2), (5, '小组A2', 2), (6, '小组B1', 3); -- 使用递归查询获取组织结构的层级关系 WITH RecursiveCTE AS ( SELECT ID, Name, ParentID, 0 AS Level FROM Organization WHERE ParentID IS NULL UNION ALL SELECT o.ID, o.Name, o.ParentID, Level + 1 FROM Organization o INNER JOIN RecursiveCTE r ON o.ParentID = r.ID ) SELECT ID, Name, Level FROM RecursiveCTE ORDER BY Level, ID; ``` 上述示例中,我们首先创建了一个名为Organization的表,用于存储组织结构数据。然后插入了一些示例数据。接下来,使用递归查询通过递归联接获取组织结构的层级关系。在递归查询中,我们使用了一个公共表表达式(CTE)来定义递归部分和终止条件。最后,通过查询RecursiveCTE表获取结果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值