SQL查询指定节点及其所有父节点的方法

--查询ID = ‘009‘的所有父节点
SET @ID = ‘009‘
;WITH T AS
(
  SELECT ID , PID , NAME
  FROM TB
  WHERE ID = @ID
  UNION ALL
  SELECT A.ID , A.PID , A.NAME
  FROM TB AS A JOIN T AS B ON A.ID = B.PID
)
SELECT * FROM T ORDER BY ID
/*
ID   PID  NAME
---- ---- ----------
001  NULL 广东省
003  001  深圳市
007  003  宝安区
009  007  龙华镇
create table tb(id varchar(3) , pid varchar(3) , name varchar(10))
insert into tb values(‘001‘ , null  , ‘广东省‘)
insert into tb values(‘002‘ , ‘001‘ , ‘广州市‘)
insert into tb values(‘003‘ , ‘001‘ , ‘深圳市‘)
insert into tb values(‘004‘ , ‘002‘ , ‘天河区‘)
insert into tb values(‘005‘ , ‘003‘ , ‘罗湖区‘)
insert into tb values(‘006‘ , ‘003‘ , ‘福田区‘)
insert into tb values(‘007‘ , ‘003‘ , ‘宝安区‘)
insert into tb values(‘008‘ , ‘007‘ , ‘西乡镇‘)
insert into tb values(‘009‘ , ‘007‘ , ‘龙华镇‘)
insert into tb values(‘010‘ , ‘007‘ , ‘松岗镇‘)
go

--查询各节点的父路径函数(从父到子)
create function f_pid1(@id varchar(3)) returns varchar(100)
as
begin
  declare @re_str as varchar(100)
  set @re_str = ‘‘
  select @re_str = name from tb where id = @id
  while exists (select 1 from tb where id = @id and pid is not null)
    begin
      select @id = b.id , @re_str = b.name + ‘,‘ + @re_str from tb a , tb b where a.id = @id and a.pid = b.id
    end
  return @re_str
end
go
--查询各节点的父路径函数(从子到父)
create function f_pid2(@id varchar(3)) returns varchar(100)
as
begin
  declare @re_str as varchar(100)
  set @re_str = ‘‘
  select @re_str = name from tb where id = @id
  while exists (select 1 from tb where id = @id and pid is not null)
    begin
      select @id = b.id , @re_str = @re_str + ‘,‘ + b.name from tb a , tb b where a.id = @id and a.pid = b.id
    end
  return @re_str
end
go

select * ,
       dbo.f_pid1(id) [路径(从父到子)] ,
       dbo.f_pid2(id) [路径(从子到父)]
from tb order by id

drop function f_pid1 , f_pid2
drop table tb

/*
id   pid  name    路径(从父到子)               路径(从子到父)
---- ---- ------  ---------------------------  ----------------------------
001  NULL 广东省  广东省                       广东省
002  001  广州市  广东省,广州市                广州市,广东省
003  001  深圳市  广东省,深圳市                深圳市,广东省
004  002  天河区  广东省,广州市,天河区         天河区,广州市,广东省
005  003  罗湖区  广东省,深圳市,罗湖区         罗湖区,深圳市,广东省
006  003  福田区  广东省,深圳市,福田区         福田区,深圳市,广东省
007  003  宝安区  广东省,深圳市,宝安区         宝安区,深圳市,广东省
008  007  西乡镇  广东省,深圳市,宝安区,西乡镇  西乡镇,宝安区,深圳市,广东省
009  007  龙华镇  广东省,深圳市,宝安区,龙华镇  龙华镇,宝安区,深圳市,广东省
010  007  松岗镇  广东省,深圳市,宝安区,松岗镇  松岗镇,宝安区,深圳市,广东省

(所影响的行数为 10 行)
*/
时间: 2024-11-05 20:31:51

SQL查询指定节点及其所有父节点的方法的相关文章

[SQL]T-Sql 递归查询(给定节点查所有父节点、所有子节点的方法)

-- 查找所有父节点with tab as( select Type_Id,ParentId,Type_Name from Sys_ParamType_V2_0 where Type_Id=316--子节点 union all select b.Type_Id,b.ParentId,b.Type_Name  from  tab a,--子节点数据集  Sys_ParamType_V2_0 b  --父节点数据集 where a.ParentId=b.Type_Id  --子节点数据集.paren

C# TreeView控件 展开指定子节点的所有父节点

通常,我们需要的功能更多的是通过展开某一个父节点同时展开所有的子节点(即:联动),但是有时候我们也需要展开某一个节点之上的所有父节点,直到当前节点,例如在删除某一个节点时,不想删除之后所有节点有折叠,这时候就需要这种功能.这样说可能不好理解,也可能是本人语言表达能力欠佳,我们来看一个图: 通常我们都是点击根节点"1"展开所有的节点,如上.但是现在我们要删除节点"11111",删除之后是自动展开到"1111",即: 注意两个图是不一样的. 如何实现

T-Sql 递归查询(给定节点查所有父节点、所有子节点的方法)

-- 查找所有父节点with tab as( select Type_Id,ParentId,Type_Name from Sys_ParamType_V2_0 where Type_Id=316--子节点 union all select b.Type_Id,b.ParentId,b.Type_Name  from  tab a,--子节点数据集  Sys_ParamType_V2_0 b  --父节点数据集 where a.ParentId=b.Type_Id  --子节点数据集.paren

找到树中指定id的所有父节点

const data = [{ id: 1, children: [{ id: 2, children: [{ id: 3, }, { id: 4, }], }], }, { id: 5, children: [{ id: 6, }], }]; let nodes = []; function getParentNodes(id, tree) { _getParentNodes([], id, tree); return nodes; } function _getParentNodes(his

easyui Tree模拟级联勾选cascadeCheck,节点选择,父节点自动选中,节点取消,父节点自动取消选择,节点选择,所有子节点全部选择,节点取消,所有子节点全部取消勾选

最近项目中用到easyui tree,发现tree控件的cascadeCheck有些坑,不像miniui 的tree控件,级联勾选符合业务需求,所以就自己重新改写了onCheck事件,符合业务需求.网上百度了很多资料,都没有完全符合自己业务场景的,所以就自己动手写咯. 先说一下自己的业务需求: 1.选中节点,上级以及所有直系上级节点自动选中,所有下级子孙节点全部自动选中: 2.取消选择节点,如果兄弟节点都未选择,则上级以及所有直系上级节点自动取消选择,所有下级子孙节点全部取消选中. 这里说一下c

sql查询指定表外键约束

//////////////////查询指定表外键约束select a.name as 约束名, object_name(b.parent_object_id) as 外键表, d.name as 外键列, object_name(b.referenced_object_id) as 主健表, c.name as 主键列 from sys.foreign_keys A inner join sys.foreign_key_columns B on A.object_id=b.constraint

SQL查询一个表的总记录数的方法

一.简单查询语句 1. 查看表结构 SQL>DESC emp; 2. 查询所有列 SQL>SELECT * FROM emp; 3. 查询指定列 SQL>SELECT empmo, ename, mgr FROM emp; SQL>SELECT DISTINCT mgr FROM emp; 只显示结果不同的项 4. 查询指定行 SQL>SELECT * FROM emp WHERE job='CLERK'; 5. 使用算术表达式 SQL>SELECT ename, sa

将子节点的所有父节点ID合并成一个字符串,并更新表

begin for cur_dept in (select SLCATALOG_ID from T_GIS_SLCATALOG) loop UPDATE T_GIS_SLCATALOG SET PATH = (SELECT listagg(SLCATALOG_ID, ',') WITHIN GROUP (ORDER BY SLCATALOG_ID) FROM (SELECT * FROM T_GIS_SLCATALOG START WITH SLCATALOG_ID = cur_dept.SLC

Sql查询指定期限内信息

3天前的所有数据:SELECT * FROM 表名 WHERE DATEDIFF(dd,datetime类型字段,getdate())=3: 今天的所有数据:SELECT * FROM 表名 WHERE DATEDIFF(dd,datetime类型字段,getdate())=0: 昨天的所有数据:SELECT * FROM 表名 WHERE DATEDIFF(dd,datetime类型字段,getdate())=1: 7天内的所有数据:SELECT * FROM 表名 WHERE DATEDIF