我有这个小问题。
该表基本上如下所示
主题
ParentSubjectId
引用主题表本身。
它可以下降到很多级别(没有特定的级别数)
示例(仅为本示例使用国家/地区):
1.Europe
2.America
1.1 France
1.1 Italy
2.1 USA
2.2 Canada
1.1.1 Paris
1.2.1 Rome
依旧......
SubjectID是Guid ParentSubjectID也是一个GUID。
示例概述:http://i.imgur.com/a2u2CfT.png
它甚至可以无限期地下降(甚至可能达到街道数量级)我的问题是:
给定一个主题(无论深度)。
我想获得该主题的顶级父母(在这种情况下为Europe/America
)
我该怎么做? 是否可以使用Basic SQL查询?
请注意我根本无法修改数据库(我从现有数据库中查询数据)
答案 0 :(得分:1)
写为:
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
答案 1 :(得分:0)
这很容易处理,只需添加新列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
答案 2 :(得分:0)
对于它可能关心的人,我对@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