如何从一个值(可能是父级或子级)获取同一层次表中的父级和子级?

时间:2017-05-02 18:17:48

标签: sql sql-server tsql

考虑以下表格:

表:类别

CategoryID int identity PK <--.
ParentID int NULL FK --->-----'
Name varchar(50)

它允许同一个表中的父/子关系:

CategoryID   ParentID   Name
--------------------------------
1            NULL       Parent A
2            1          Child A

表:项目

ProjectID int identity PK
Name varchar(50) NOT NULL

我还有项目和类别的联结表

表:ProjectCategory

ProjectID int PK FK
CategoryID int PK FK

ProjectID    CategoryID
--------------------------------
1            2 <-- Either a parent or child category

可以将项目分配给父类别或子类别,但不能同时分配两者。实质上,如果将项目分配给子类别,则无论如何都将其与父类别相关联,并且我不想要这样:

ProjectID    CategoryID
--------------------------------
1            1 <-- Parent
1            2 <-- Child of Parent 1

这一切都很好,但对于我的应用程序,我需要将事情弄平,并得到一个如下所示的结果集/行:

ProjectID    ParentCategoryID   ChildCategoryID
-----------------------------------------------
1            1                  2

所以问题是,我不确定为应用程序提供这两者的最佳方法,但它需要在单个SQL查询中完成,从而产生单行数据。

更新

我给自己发了一个答案,但如果有更好的方法,请把它拆开。

2 个答案:

答案 0 :(得分:1)

我可能已经找到了自己的答案,但如果有更好的方法,我会很快找到更好的答案。

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

答案 1 :(得分:0)

我假设您在CategoryID上从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