SQL server 根据子级查询根父级

小编做惯了根据父级查子级,可是怎么也没想到有一天会遇到根据子级查根父级这种需求,小编起初想通过C#,但是小编最后并没有做到合适的方法,那小编只能通过SQL server的方式来解决了
推算历程一:

with cte(FieldID,ParentId,FieldName)
as
(--下级父项
select FieldID,ParentId,FieldName from IntellManuSchool_Field where FieldID in (1,10) --子级id
union all
--递归结果集中的父项
select t.FieldID,t.ParentId,t.FieldName from IntellManuSchool_Field as t
inner join cte as c on t.FieldID = c.ParentId

)
select FieldID,ParentId,FieldName from cte where ParentId=0 group by FieldID,ParentId,FieldName order by FieldID asc

小编在网上查询很多后都会遇到该方法,小编使用该方法虽然查到的是正确的,但是此方法对连表查询并不友好,他需要定义一个变量,然后通过变量(子级)查询,却没办法直接连表查询所有的
推算历程二:

select child.FieldID as ChildFieldID,Parent.FieldID as ParentFieldID,
Parent.ParentId,Parent.FieldName as ParentName from IntellManuSchool_Field as Parent 
inner join IntellManuSchool_Field as child on Parent.FieldID=child.ParentId 
where Parent.ParentId=0 
group by child.FieldID ,Parent.FieldID ,Parent.ParentId,Parent.FieldName--该方法已经可以查询所有子类对应父类的列表

小编查来查去居然查到了小编之前的一篇博客Sql server 同一张表中ID,Name,ParentID要求同时查出ID对应的Name,和ParentID对应的Name,并从中得到了启发,方式如上代码,不断的总结还是很好的,因为自己也不知道哪天又会遇到此类问题

下面是小编最后的关联,table逻辑很复杂,小编只是写了一个代替,由于一行数据最终存在含有两个一级类型的现象,所以需要通过stuff的方式实现

select * from table a left join 
(
	SELECT PackegId,Title,Field,
	STUFF((SELECT ','+ParentName FROM (select PackegId,Title,Field,ParentName from IntellManuSchool_CoursePackage as a 
	left join  (select child.FieldID as ChildFieldID,Parent.FieldID as ParentFieldID,Parent.ParentId,
	Parent.FieldName as ParentName from IntellManuSchool_Field as Parent 
	inner join IntellManuSchool_Field as child on Parent.FieldID=child.ParentId 
	where Parent.ParentId=0 group by child.FieldID ,Parent.FieldID ,Parent.ParentId,Parent.FieldName ) as b 
	on CHARINDEX(','+LTRIM(b.ParentFieldID)+',',','+a.Field+',')>0 or CHARINDEX(','+LTRIM(b.ChildFieldID)+',',','+a.Field+',')>0 
	group by PackegId,Title,Field,ParentName) as a WHERE PackegId=T.PackegId FOR XML PATH('')),1,1,'') AS ParentName  
	FROM (select PackegId,Title,Field,ParentName from IntellManuSchool_CoursePackage as a 
	left join  (select child.FieldID as ChildFieldID,Parent.FieldID as ParentFieldID,Parent.ParentId,Parent.FieldName as ParentName from IntellManuSchool_Field as Parent 
	inner join IntellManuSchool_Field as child on Parent.FieldID=child.ParentId where Parent.ParentId=0 
	group by child.FieldID ,Parent.FieldID ,Parent.ParentId,Parent.FieldName ) as b 
	on CHARINDEX(','+LTRIM(b.ParentFieldID)+',',','+a.Field+',')>0 or CHARINDEX(','+LTRIM(b.ChildFieldID)+',',','+a.Field+',')>0 
	group by PackegId,Title,Field,ParentName) T GROUP BY PackegId,Title,Field
) i on a.PackegId = i.PackegId
where  a.PackegId in (3,4,5,6,8,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,27,28,29,30,31,32,33,34,35,36,37,
38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,55,56,57,58,59,60,61,62,63,64,65,66,67,69,70,71,72,73,74,75,
76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,1103,1104)

顺便讲讲如何在存储过程中找找自己的错误代码问题技巧,首先通过print @theStr可以打印变量的值,当变量为SQL server语句时该方法还是屡试不爽的,再者通过exec 存储过程名 参数可以执行存储过程,两者结合找存储过程的报错问题就会效率很高

最近心得:作为一名全栈,小编真的是很累,忙完前台忙后台,忙完后台忙数据库,不管哪一种隔一段时间没写,再突然安排该需求时,小编就突然需要花一段时间才能适应,短则2-3天,长则5-6天,不过随着越做越多,小编觉得越到后面数据库永远都是最重要的内容,因为前端后端怎么实现的可以照搬照抄,而数据库越到后面就越是在和逻辑打交道,像极了高中数学考试

2022-08-19更新,小编今天又发现一种更简单的查询方法子查询

select a.PackegId,a.Title,a.Field,a.StarRating,isnull(b.StudyUserCount,0) as StudyUserCount,a.AddTime,
(SELECT   STUFF
 ((SELECT   ',' + CONVERT(VARCHAR, FieldName)
   FROM IntellManuSchool_Field WHERE   charindex(',' + ltrim(FieldID) + ',', ',' +
     (SELECT   STUFF
        ((SELECT   ',' + CONVERT(VARCHAR, ParentId) FROM IntellManuSchool_Field WHERE   charindex(',' + ltrim(FieldID) + ',', ',' + a.Field + ',') > 0 AND FieldType = 1 FOR XML PATH('')), 1, 1, '')) + ',') > 0 AND FieldType = 0 FOR XML PATH('')), 1, 1, '')) AS OneLevelField  from IntellManuSchool_CoursePackage as a

今日心得:逻辑的美就在于,原理很简单,但是做起来却有千万般变化,谁能在看到需求后想到最合适的原理和逻辑去实现,并使用最简单的方法做出程序,谁就是开发最屌的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值