Reputation: 14727
I use SQL Server 2014 for my project. I have three tables:
Table A:
Column: id
Table B:
Column: id, id_of_Table_A
Table C:
Column: id, id_of_Table_B, category
The relationship between A and B is one to many
The relationship between B and C is one to many
In Table C, there are 10 category values for the category
column, but I am interested only in three categories (cat1, cat2, cat3). I hope to query and produce the following results for the three categories:
id_of_Table_A, category, category, category
I have the following statement:
select a.id, c.category from Table_C c
join Table_B b on b.id = c.id_of_Table_B
join Table_A a on a.id = b.id_of_Table_A
where c.category = 'cat1' and a.id in (1, 2, 3)
But this statement only lists
id_of_Table_A, cat1
which contains only cat1 of a given id_of_Table_A. I hope to have something like:
1, cat1, cat2, cat3
if cat1, cat2, and cat3 exists in Table C for the given id 1
in Table A.
If a single statement is unable to produce the desired results, then a stored procedure is okay.
Update
In the following example results,
1, cat1, cat2, cat3
cat1, cat2, cat3 must come from three different records in Table B. Suppose we have these tables and rows:
Table A: 1,2
Table B: (1,1), (2,1), (3,1), (4,2), (5,2), (6,2)
Table c: (1,1,'cat3'), (2,2,'cat1'), (3,3,'cat2'), (4,4,'cat1'), (5,5,'cat4'), (6,6,'cat2')
Then the expected results should be:
1, cat1, cat2, cat3
Basically, the relationships of the tables form a tree. I hope to find the root (Table A) with leaves being cat1, cat2, and cat3 on non-overlapping paths from the root.
Upvotes: 0
Views: 289
Reputation: 9470
You can combine all categories for id_of_b
in a single xml
value and then show categories in columns. Something like this.
declare @a table(id int)
declare @b table(id int,id_of_a int)
declare @c table(id int,id_of_b int,category varchar(50))
insert @a values(1),(2)
insert @b values(1,1),(2,1),(3,2)
insert @c values(1,1,'cat1'),(2,1,'cat2'),(3,1,'cat3'),(4,2,'cat4')
;with cte as(
select a.id,
cast((select category from @c c where c.id_of_b = b.id for xml auto,root,type) as xml) xcat
from @a a inner join @b b on a.id = b.id_of_a
)
select id,
t.v.value('c[1]/@category','varchar(50)') cat1,
t.v.value('c[2]/@category','varchar(50)') cat2,
t.v.value('c[3]/@category','varchar(50)') cat3
from cte
cross apply xcat.nodes('root') t(v)
Updated answer for updated question
declare @a table(id int)
declare @b table(id int,id_of_a int)
declare @c table(id int,id_of_b int,category varchar(50))
insert @a values(1),(2)
insert @b values (1,1), (2,1), (3,1), (4,2), (5,2), (6,2)
insert @c values (1,1,'cat3'), (2,2,'cat1'), (3,3,'cat2'), (4,4,'cat1'), (5,5,'cat4'), (6,6,'cat2')
;with cte as(
select a.id,
cast((select category from @c c inner join @b b on c.id_of_b = b.id
where b.id_of_a=a.id
for xml auto,root,type) as xml) xcat
from @a a
)
select id,
t.v.value('c[1]/@category','varchar(50)') cat1,
t.v.value('c[2]/@category','varchar(50)') cat2,
t.v.value('c[3]/@category','varchar(50)') cat3
from cte
cross apply xcat.nodes('root') t(v)
Upvotes: 1