SQL-如何在自引用表中获取给定值的顶级父级
我有个小问题 该表基本上如下所示 主题SQL-如何在自引用表中获取给定值的顶级父级,sql,sql-server,Sql,Sql Server,我有个小问题 该表基本上如下所示 主题 主体 主题名 父母主体 ParentSubjectId引用主题表本身。 它可以下降很多级别(没有具体的级别数) 示例(仅为了本示例而使用国家): 等等 主语是Guid ParentSubjectID也是一个GUID 示例概述: 它甚至可以无限期地降低级别(甚至可能降低到街道编号级别) 我的问题是: 给定一个主题(无论深度)。 我想得到该科目的顶级家长(Europe/America) 我该怎么做? 是否可以使用基本SQL查询 请注意,我根本无法修改数据库
- 主体
- 主题名
- 父母主体
ParentSubjectId
引用主题表本身。
它可以下降很多级别(没有具体的级别数)
示例(仅为了本示例而使用国家):
等等
主语是Guid
ParentSubjectID也是一个GUID
示例概述:
它甚至可以无限期地降低级别(甚至可能降低到街道编号级别)
我的问题是:
给定一个主题(无论深度)。
我想得到该科目的顶级家长(Europe/America
)
我该怎么做?
是否可以使用基本SQL查询
请注意,我根本无法修改数据库(我正在从现有数据库查询数据)这很容易处理,只需添加新的列HID(varchar)并填充即可
01 Europe
02 America
0101 France
0102 Italy
010101 Paris
选择父项:
DECLARE @childHID varchar(10) = '010101' --Paris
SELECT A.ID, A.Name
FROM Address A
WHERE A.HID = SUBSTRING(@childHID, 1, 2) -- first level
您还可以获得您的所有分支:
SELECT *
FROM Address
WHERE HID LIKE '01%'
ORDER BY HID
写为:
declare @Subject as varchar(max)
set @Subject = 'Rome'; -- set subject name here
WITH SubjectCTE AS
(
SELECT SubjectId , SubjectName , ParentSubjectId
FROM Subject
WHERE SubjectName = @Subject
UNION ALL
SELECT C.SubjectId , C.SubjectName , C.ParentSubjectId
FROM SubjectCTE AS P
JOIN Subject AS C
ON P.ParentSubjectId = C.SubjectId
)
,SubjectCTE2 as
(
SELECT SubjectId , SubjectName , ParentSubjectId,
Row_Number() over ( order by SubjectId asc) as rownum
FROM SubjectCTE
)
select SubjectName as RequiredParentName
from SubjectCTE2
where rownum =1
我对@Mini的查询做了一些改进,这样即使最顶端的父项链接到它自己,它也会停止,即使子项的父项id较小,它也会工作:
declare @Subject as varchar(max)
set @Subject = 'Rome';
WITH SubjectCTE AS
(
SELECT * FROM Subject
WHERE SubjectName = @Subject
UNION ALL
SELECT C.*
FROM SubjectCTE AS P
JOIN Subject AS C
ON P.ParentSubjectId = C.SubjectId
WHERE P.ParentSubjectId != P.SubjectId
) SELECT SubjectName FROM SubjectCTE
WHERE ParentSubjectId = SubjectId
OR ParentSubjectId IS NULL
我想使用递归公共表表达式应该是可行的。显示正确的示例数据。哪个是父id,哪个是主体idIs ParentSubjectId一个varchar列,数据为“1.1”,“1.2”??请发布示例表数据。不,它们是guid,我已经在我的原始帖子中添加了一个图片链接。应该很清楚,我猜我不能对数据库做任何修改。我在原来的帖子中添加了一个图片链接,解释我的桌子是什么样子的。id也是guid。
declare @Subject as varchar(max)
set @Subject = 'Rome';
WITH SubjectCTE AS
(
SELECT * FROM Subject
WHERE SubjectName = @Subject
UNION ALL
SELECT C.*
FROM SubjectCTE AS P
JOIN Subject AS C
ON P.ParentSubjectId = C.SubjectId
WHERE P.ParentSubjectId != P.SubjectId
) SELECT SubjectName FROM SubjectCTE
WHERE ParentSubjectId = SubjectId
OR ParentSubjectId IS NULL