小编做惯了根据父级查子级,可是怎么也没想到有一天会遇到根据子级查根父级这种需求,小编起初想通过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天,不过随着越做越多,小编觉得越到后面数据库永远都是最重要的内容,因为前端后端怎么实现的可以照搬照抄,而数据库越到后面就越是在和逻辑打交道,像极了高中数学考试