SqlServer父节点与子节点查询及递归
sql 一条语句查询所有父节点

sql 一条语句查询所有父节点在SQL中,查询所有父节点通常涉及递归查询或者使用层级查询(CTE:Common Table Expression)来遍历具有父子关系的层次结构数据。
以下是一个基于MySQL的示例,假设我们有一个名为categories的表,其中包含id和parent_id字段,表示每个节点及其父节点:sqlWITH RECURSIVE category_tree AS (SELECT id, parent_id, nameFROM categoriesWHERE parent_id IS NULL -- 根节点UNION ALLSELECT c.id, c.parent_id, FROM categories cJOIN category_tree ct ON c.parent_id = ct.id)SELECT * FROM category_tree;这条语句首先定义了一个名为category_tree的递归公共表表达式,它从根节点开始(即parent_id为空的所有节点),然后递归地将每个节点的子节点加入到结果集中。
如果你想要查询某个特定节点的所有父节点,则可以稍微修改这个查询:sqlWITH RECURSIVE ancestor_tree AS (SELECT id, parent_id, nameFROM categoriesWHERE id = :target_id -- 替换为你要查找其父节点的具体节点IDUNION ALLSELECT c.id, c.parent_id, FROM categories cJOIN ancestor_tree at ON c.id = at.parent_id)SELECT * FROM ancestor_tree ORDER BY id ASC; -- 从最近的父节点到最远的祖先排序在这个查询中,你将找到指定节点(:target_id)的所有祖先节点,按层级从近到远排列。
sql server 递归查询父级字段-概述说明以及解释

sql server 递归查询父级字段-概述说明以及解释1.引言1.1 概述概述部分的内容可以从以下几个方面展开:首先,简要介绍递归查询的概念。
递归查询是指在数据库中通过反复执行相同的查询操作,从而获取多层次关系数据的一种查询方式。
递归查询常用于父子关系数据的处理,比如组织结构、分类层级等。
其次,说明递归查询的重要性和实际应用场景。
在实际的数据操作中,很多时候需要查询某个节点的所有上级或者下级节点,而递归查询正是解决这类问题的有效方式。
递归查询可以帮助我们实现更高效的数据处理和管理,提高数据的可用性和灵活性。
然后,提及本文将要介绍的内容。
本文主要讨论在SQL Server 数据库中如何进行递归查询父级字段的操作。
首先将介绍递归查询的原理和概念,然后具体介绍SQL Server 中的递归查询实现方式。
最后,强调本文的目的和意义。
通过深入研究和理解递归查询父级字段的相关知识,读者可以更加灵活地处理和管理数据库中的父子关系数据,提升数据处理效率和准确性。
同时,本文也为读者提供了解决类似问题的实际操作指导,帮助读者在实际工作中快速解决相关的数据查询和处理任务。
1.2文章结构1.2 文章结构本文将围绕SQL Server中递归查询父级字段展开进行介绍。
文章主要包括三个部分:第一部分是引言,将对递归查询和父级字段的概念进行概述。
我们会介绍递归查询的原理以及其在数据库领域中的重要性。
同时,我们也会简要介绍本文的结构和目的,以帮助读者了解文章的整体框架。
第二部分是正文,将详细介绍SQL Server中实现递归查询的方式。
我们会探讨不同的递归查询方法,并深入讨论它们的实现原理和适用场景。
通过这一部分的学习,读者将对如何在SQL Server中使用递归查询来处理父级字段有一个全面的了解。
第三部分是结论,我们将重点探讨递归查询在父级字段中的应用。
我们会通过实际案例和示例来说明如何利用递归查询来处理具有父子关系的数据,并分析其优缺点和适用性。
SQLServer使用WITHAS递归查找

在SQL2008以上版本有一个 WITH CTE AS 的用法,可以实现相应的业务。(只能使用一个with,多个CTE中间用逗号分隔)
例:
1 -- 定义一个temp的"临时表" 2 with temp as 3( 4 -- 树根 5 select * from COM_DataDictionaryInfo where ID = 'F27F0114-F94F-452E-AD13-18B331526223' 6 7 union all 8 -- 递归 9 select b.* from temp a 10 inner join COM_DataDictionaryInf 13 14 -- 这里一定要直接使用temp 15 select * from temp
您使用的浏览器不受支持建议使用新版浏览器
SQLServer使用 WITHAS递归查找
很多时候我们会在数据库表中存储树结构的数据,如菜单:一级菜单、二级菜单、三级菜单...
如果树结构层次比较多,如何能够在只知道某节点的情况下,找到此节点下的所有子级数据呢?
在.NET后台可以定义一个递归函数,通过递归可以找到相应的数据。
SqlServer父节点与子节点查询及递归

SqlServer⽗节点与⼦节点查询及递归在最近⽼是⽤到这个SQL,所以记下来了:1:创建表CREATE TABLE [dbo].[BD_Booklet]([ObjID] [int] IDENTITY(1,1) NOT NULL,[ParentID] [int] NULL,[ObjLen] [int] NULL,[ObjName] [nvarchar](50) NULL,[ObjUrl] [nvarchar](200) NULL,[ObjExpress] [nvarchar](500) NULL,[ObjTime] [nvarchar](50) NULL,[ObjUID] [nvarchar](10) NULL,[ObjDemo] [text] NULL,CONSTRAINT [PK_BD_Booklet] PRIMARY KEY CLUSTERED([ObjID] ASC)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]GO2:添加数据(⾃⼰添加)3:根据⽗节点查询⼦节点信息(所有⼦节点,包括⼦节点的⼦节点)--公⽤表表达式实现⽗节点查询⼦节点DECLARE @ParentID intSET @ParentID='1'with CTEGetChild as(select * from BD_Booklet where ParentID=@ParentIDUNION ALL(SELECT a.* from BD_Booklet as a inner joinCTEGetChild as b on a.ParentID=b.ObjID))SELECT * FROM CTEGetChild4:根据节点得到最初始的⽗节点(根节点)()--公⽤表表达式实现⼦节点查询⽗节点DECLARE @ChildID intSET @ChildID=6DECLARE @CETParentID intselect @CETParentID=ParentID FROM BD_Booklet where ObjID=@ChildIDwith CTEGetParent as(select * from BD_Booklet where ObjID=@CETParentIDUNION ALL(SELECT a.* from BD_Booklet as a inner joinCTEGetParent as b on a.ObjID=b.ParentID)) SELECT * FROM CTEGetParent说明|:近期发现该⽅法只能查询出三级,对于4级和5级的没有办法。
Sql递归查询

Sql递归查询Sql 递归查询(给定节点查所有⽗节点、所有⼦节点的⽅法)-- 查找所有⽗节点with tab as(select Type_Id,ParentId,Type_Name from Sys_ParamType_V2_0 where Type_Id=316--⼦节点union allselect b.Type_Id,b.ParentId,b.Type_Namefromtab a,--⼦节点数据集Sys_ParamType_V2_0 b --⽗节点数据集where a.ParentId=b.Type_Id --⼦节点数据集.parendID=⽗节点数据集.ID)select * from tab;-- 查找所有⼦节点with tab as(select Type_Id,ParentId,Type_Name from Sys_ParamType_V2_0 where Type_Id=1--⽗节点union allselect b.Type_Id,b.ParentId,b.Type_Namefromtab a,--⽗节点数据集Sys_ParamType_V2_0 b--⼦节点数据集where b.ParentId=a.Type_Id --⼦节点数据集.ID=⽗节点数据集.parendID)select * from tab;--查找从⼦节点到定级节点的路径with tab as(select Type_Id,ParentId,Type_Name,cast(Type_Id as varchar(100)) as fulltypeidfrom SKU_ProductType where Type_Id=423--⼦节点union allselectb.Type_Id,b.ParentId,b.Type_Name,cast(a.fulltypeid+','+cast(b.Type_Id as nvarchar(100)) as varchar(100)) as fulltypeidfromtab a,--⼦节点数据集SKU_ProductType b --⽗节点数据集where a.ParentId=b.Type_Id --⼦节点数据集.parendID=⽗节点数据集.ID)select * from tab ;--------------结果--------------423410蜂花粉423410347蜂产品423,4103475营养⾷品423,410,34750健康保健423,410,347,5View Code。
SQL递归树子父节点相互查询

SQL递归树⼦⽗节点相互查询if object_id('[tb]') is not null drop table [tb]gocreate table [tb]([modeid] int,modename varchar(20),parentid int)insert [tb]select 100 ,'商品管理', 0 union allselect 101 ,'定单管理', 0 union allselect 102 ,'⽤户管理', 0 union allselect 104 ,'学院⼴告', 0 union allselect 105 ,'系统设置', 0 union allselect 106 ,'附件管理', 0 union allselect 107 ,'商品管理', 100 union allselect 108 ,'明细管理', 100 union allselect 109 ,'物流管理', 100 union allselect 110 ,'商品信息管理', 107 union allselect 111 ,'商品分类管理', 107 union allselect 112 ,'回收站管理', 107 union allselect 114 ,'团购管理', 108 union allselect 115 ,'拍卖管理', 108 union allselect 116 ,'优惠管理', 108 union allselect 117 ,'会员管理', 102 union allselect 118 ,'会员卡管理', 102 union allselect 119 ,'资⾦管理', 102 union allselect 120 ,'管理员管理', 102 union allselect 121 ,'添加管理员', 120 union allselect 122 ,'修改管理员', 120go--查所有⼦结点if object_id('f_getC') is not null drop function f_getCgocreate function f_getC(@id int)returns @re table(id int,level int,sort varchar(10))asbegindeclare @l intset @l=0insert @re select @id,@l,nullwhile @@rowcount>0beginset @l=@l+1insert @re select a.modeid,@l,ltrim(isnull(b.sort,a.modeid)) from tb as a,@re as bwhere b.id=a.parentid and b.level=@l-1endupdate @re set level = level -1returnendgoselect a.modeid,a.parentid,REPLICATE(' ',b.level) +'┝'+a.modename,b.level,b.sort from tb a,f_getC(0) bwhere a.modeid=b.idorder by case when b.level<2 then 0 else 1 end,b.sort,b.level/*modeid parentid sort level----------- ----------- -------------------------------------------------- ---------- -----------100 0 ┝商品管理 100 0107 100 ┝商品管理 100 1108 100 ┝明细管理 100 1109 100 ┝物流管理 100 1101 0 ┝定单管理 101 0102 0 ┝⽤户管理 102 0117 102 ┝会员管理 102 1118 102 ┝会员卡管理 102 1119 102 ┝资⾦管理 102 1120 102 ┝管理员管理 102 1104 0 ┝学院⼴告 104 0105 0 ┝系统设置 105 0106 0 ┝附件管理 106 0110 107 ┝商品信息管理 100 2111 107 ┝商品分类管理 100 2112 107 ┝回收站管理 100 2114 108 ┝团购管理 100 2115 108 ┝拍卖管理 100 2116 108 ┝优惠管理 100 2121 120 ┝添加管理员 102 2122 120 ┝修改管理员 102 2(所影响的⾏数为 21 ⾏)*/--查所有⼦结点,带路径与排序if object_id('f_getC') is not null drop function f_getCgocreate function f_getC(@id int)returns @re table(id int,level int,sort varchar(100),path varchar(500))asbegindeclare @l intset @l=0insert @reselect [modeid],@l,right('00000'+ltrim(modeid),5),modenamefrom tb where parentid=@idwhile @@rowcount>0beginset @l=@l+1insert @reselect a.modeid,@l,b.sort+right('00000'+ltrim(a.modeid),5),b.path+' - '+a.modenamefrom tb as a,@re as bwhere b.id=a.parentid and b.level=@l-1endupdate @re set level = levelreturnendgoselect a.modeid,a.parentid,REPLICATE(' ',b.level) +'┝'+a.modename,b.level,b.sort ,b.path from tb a,f_getC(0) b where a.modeid=b.idorder by sort/*modeid parentid level----------- ----------- -------------------- ----------- -------------------- ----------------------------------------100 0 ┝商品管理 0 00100 商品管理107 100 ┝商品管理 1 0010000107 商品管理 - 商品管理110 107 ┝商品信息管理 2 001000010700110 商品管理 - 商品管理 - 商品信息管理111 107 ┝商品分类管理 2 001000010700111 商品管理 - 商品管理 - 商品分类管理112 107 ┝回收站管理 2 001000010700112 商品管理 - 商品管理 - 回收站管理108 100 ┝明细管理 1 0010000108 商品管理 - 明细管理114 108 ┝团购管理 2 001000010800114 商品管理 - 明细管理 - 团购管理115 108 ┝拍卖管理 2 001000010800115 商品管理 - 明细管理 - 拍卖管理116 108 ┝优惠管理 2 001000010800116 商品管理 - 明细管理 - 优惠管理109 100 ┝物流管理 1 0010000109 商品管理 - 物流管理101 0 ┝定单管理 0 00101 定单管理102 0 ┝⽤户管理 0 00102 ⽤户管理117 102 ┝会员管理 1 0010200117 ⽤户管理 - 会员管理118 102 ┝会员卡管理 1 0010200118 ⽤户管理 - 会员卡管理119 102 ┝资⾦管理 1 0010200119 ⽤户管理 - 资⾦管理120 102 ┝管理员管理 1 0010200120 ⽤户管理 - 管理员管理121 120 ┝添加管理员 2 001020012000121 ⽤户管理 - 管理员管理 - 添加管理员122 120 ┝修改管理员 2 001020012000122 ⽤户管理 - 管理员管理 - 修改管理员104 0 ┝学院⼴告 0 00104 学院⼴告105 0 ┝系统设置 0 00105 系统设置106 0 ┝附件管理 0 00106 附件管理(21 ⾏受影响)*/----------。
sqlservercte递归向上统计

sqlservercte递归向上统计数据字典如下通过sql可以得到如下结果select yskm,SUM(je) as je from view_dj where swdjh='321311570376851' group by yskm现在项⽬有个要求,要统计出他们⽗级科⽬的⾦额。
那怎么向上推出他的⽗级科⽬代码的⾦额,解决思路:1. 创建⼀张临时表来保存结果2. ⽤sqlserver cte 来查询出⾃⼰及⽗级所有的科⽬代码,代码如下1with cte as2 (3select a.kmcode,a.kmname,a.pidkm from sys_km a where kmcode in4 ( select t1.yskm from view_dj t1 where t1.swdjh='321311570376851' )5union all6select k.kmcode,k.kmname,k.pidkm from sys_km k inner join cte c on c.pidkm = k.kmcode7 )8select*from cteView Code查询结果如下:3.在通过cte和⾦额表关联把数据插⼊到临时表中代码如下insert into #tmphjcx select * from ( select distinct a.kmcode,a.kmname,a.pidkm,b.hjje,b.guoshui,b.dishui from cte aleft join(select t2.kmcode,(t2.kmcode+'_'+t2.kmname) as kmname,hjje=sum(je), guoshui=sum(case when t1.ic='1' then je end),dishui=sum(case when t1.ic='2' then je end) from view_dj t1 left join sys_km t2 on t2.kmcode=t1.yskm where t1.swdjh=@bmgroup by t2.kmcode,t2.kmname)bon b.kmcode=a.kmcode)c查询结果如下4.看上⾯的临时表的结果,可以看出科⽬代码顺序现在是对的,但是他们⽗级科⽬的⾦额都为空的,怎么根据下⼀级的科⽬⾦额获取上⼀级的科⽬⾦额呢5,这时我们应该按科⽬代码的长度倒序排列,逐个更新⾦额,应该我们只有计算出上⼀级的⾦额,然后再上⼀级⾦额的基础上计算出下⼀级⾦额。
sqlserver递归查询

sqlserver递归查询⽬的:获取上⼀条的数据减下⼀条并保留差值依次递减解决⽅案:1、表中数据如下:select*from test;2、要把每个⼈上⼀个FEE减当前的FEE然后再⽤减完的差值去减下⼀个FEE,并把每⼀⾏算出来的结果存放到BALANCE字段,也就是要达到这个效果,如:John的第⼀个BALANCE是当前的FEE,第⼆条就是1200-150=1050,第三条是1050-300=7503、为test表添加两个字段⽅便做递归查询alter table test add creq int;alter table test add preq int;4、先给creq赋值with t as (select NAME,ORDER_NUMBER,row_number()over(partition by NAME order by ORDER_NUMBER) creq from test)update A set A.creq=B.creqfrom test A left join t B on = and A.ORDER_NUMBER=B.ORDER_NUMBER;5、再给preq赋值,preq的值等于上⼀条的creqwith t as (select NAME,ORDER_NUMBER,lag(creq)over(partition by NAME order by ORDER_NUMBER) preq from test)update A set A.preq=B.preqfrom test A left join t B on = and A.ORDER_NUMBER=B.ORDER_NUMBER;6、编写递归查询的sqlwith CTE as (select NAME,ORDER_NUMBER,FEE,cast(FEE as numeric(17,2)) as BALANCE,creq,preq from test where creq=1union allselect ,B.ORDER_NUMBER,B.FEE,cast(A.BALANCE-B.FEE as numeric(17,2)) as BALANCE,B.creq,B.preq from CTE A inner join test B on A.creq=B.preq and =)select*from CTE order by NAME,ORDER_NUMBEROPTION(MAXRECURSION 0);OPTION(MAXRECURSION 0)的意思是递归次数⽆限制,不加这个默认是100次。