Reputation: 3260
Consider the following tables:
Table: Category
CategoryID int identity PK <--.
ParentID int NULL FK --->-----'
Name varchar(50)
It allows a parent/child relationship in the same table:
CategoryID ParentID Name
--------------------------------
1 NULL Parent A
2 1 Child A
Table: Project
ProjectID int identity PK
Name varchar(50) NOT NULL
I also have a junction table for projects and categories
Table: ProjectCategory
ProjectID int PK FK
CategoryID int PK FK
ProjectID CategoryID
--------------------------------
1 2 <-- Either a parent or child category
A project can be assigned to either a parent category, or a child category, but not both. In essence, if a project is assigned to a child category, it's relationally tied to the parent category regardless, and I don't want this:
ProjectID CategoryID
--------------------------------
1 1 <-- Parent
1 2 <-- Child of Parent 1
That's all fine, but for my application I need to flatten things out and have a result set/row that looks like this:
ProjectID ParentCategoryID ChildCategoryID
-----------------------------------------------
1 1 2
So the issue is, I'm not sure of the best way to provide both for the application, but it needs to be done in a single SQL query that results in a single row of data.
Update
I posted an answer to myself, but please tear it apart if there's a better way.
Upvotes: 0
Views: 80
Reputation: 1123
I'm assuming you have self referential foreign key on Category table from ParentID to CategoryID. You are really complicating things in your description, since the ParentID will also exist as a CategoryID, all you need is a simple join between the two tables:
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
Upvotes: 0
Reputation: 3260
I may have found my own answer, but I'll quickly take a better one if there's a better way.
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
Upvotes: 1