Sql 如何从同一分层表中的一个值(可能是父值,也可能是子值)获取父级和子级?
考虑下表: 表格:类别Sql 如何从同一分层表中的一个值(可能是父值,也可能是子值)获取父级和子级?,sql,sql-server,tsql,Sql,Sql Server,Tsql,考虑下表: 表格:类别 CategoryID int identity PK <--. ParentID int NULL FK --->-----' Name varchar(50) ProjectID int PK FK CategoryID int PK FK ProjectID CategoryID -------------------------------- 1 2 <-- Either a parent or child cate
CategoryID int identity PK <--.
ParentID int NULL FK --->-----'
Name varchar(50)
ProjectID int PK FK
CategoryID int PK FK
ProjectID CategoryID
--------------------------------
1 2 <-- Either a parent or child category
表格:项目
ProjectID int identity PK
Name varchar(50) NOT NULL
我还有一个项目和类别的连接表
表格:项目类别
CategoryID int identity PK <--.
ParentID int NULL FK --->-----'
Name varchar(50)
ProjectID int PK FK
CategoryID int PK FK
ProjectID CategoryID
--------------------------------
1 2 <-- Either a parent or child category
所以问题是,我不确定为应用程序提供这两者的最佳方式,但它需要在一个SQL查询中完成,该查询将生成一行数据
更新
我给自己贴了一个答案,但如果有更好的方法,请把它撕成碎片。我可能已经找到了自己的答案,但如果有更好的方法,我会很快选择一个更好的答案
SELECT p.*
,ISNULL(cat.ParentID, cat.CategoryID) AS ParentCategoryID
,CASE WHEN cat.ParentID IS NOT NULL THEN cat.CategoryID
END ChildCategoryID
FROM Project p
OUTER APPLY (
SELECT TOP 1 c.CategoryID, c.ParentID FROM ProjectCategory pc
INNER JOIN Category c ON c.CategoryID = pc.CategoryID
WHERE pc.ProjectID = p.ProjectID
) cat
我假设类别表上从ParentID到CategoryID有自引用外键。在您的描述中,您确实使事情复杂化了,因为ParentID也将作为CategoryID存在,所以您只需要在两个表之间进行简单的连接:
select pc.ProjectID,
coalesce(c.ParentID, c.CategoryID) as ParentCategoryID --shows category id as parent if it has no parent
case when c.ParentID is not null then c.CategoryID end as ChildCategoryID
from ProjectCategory as pc
inner join Category as c
on c.CategoryID = pc.CategoryID
不可能有孙子或更深层次的亲子关系吗?基本上没有,还没有。应用程序的解释是现在强制执行的,但由于此规则将来可能会更改,因此我在DB中以这种方式设置它。@Anand,为了简化,我更新了我的问题。感谢您花时间提供帮助。在您的示例中,如果c.ParentID为null,则此操作似乎失败。如果不是ParentID,我需要获取ParentID。请将我的答案作为我使用
ISNULL()
的示例。我肯定有可能把事情搞得太复杂了。我将更新我的问题,并尝试清除一些垃圾。谢谢@Anand的帮助。我想你的意思是,如果没有父类,它应该将类别显示为它自己的父类?如果是的话,编辑答案以反映这一点。是的,这就是我的意思。我盯着这个看了之后,脑子都被搞糊涂了。不过,您仍然需要处理ChildCategoryID
,对吗?就像我的回答一样?否则,ChildCategoryID
实际上可能是一个父类。除此之外,区别似乎是连接与外部应用。我不是SQL性能测试方面的专家。我的例子中的前1个是多余的。在测试时,我的数据有点乱。哈哈,你让自己更加困惑:)如果子类别是父类别,那么它将作为父类别显示在子类别的行中。
select pc.ProjectID,
coalesce(c.ParentID, c.CategoryID) as ParentCategoryID --shows category id as parent if it has no parent
case when c.ParentID is not null then c.CategoryID end as ChildCategoryID
from ProjectCategory as pc
inner join Category as c
on c.CategoryID = pc.CategoryID