在结果中的同一行中的同一列和同一表中显示3个不同的值

时间:2019-05-27 18:54:26

标签: sql-server

我将SQL Server 2014用于我的项目。我有三个表:

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

在表C中,category列有10个类别值,但是我只对三个类别(cat1,cat2,cat3)感兴趣。我希望针对这三个类别查询并产生以下结果:

id_of_Table_A, category, category, category

我有以下声明:

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)

但是此语句仅列出

id_of_Table_A, cat1

,其中仅包含给定id_of_Table_A的cat1。我希望有这样的东西:

1, cat1, cat2, cat3

如果对于表A中的给定ID 1,表C中存在cat1,cat2和cat3。

如果单个语句无法产生所需的结果,则存储过程可以。

更新

在以下示例结果中,

1, cat1, cat2, cat3

cat1,cat2,cat3必须来自表B中的三个不同记录。假设我们有以下表和行:

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')

那么预期结果应该是:

1, cat1, cat2, cat3

基本上,表的关系形成一棵树。我希望在根的非重叠路径上找到叶子分别为cat1,cat2和cat3的根(表A)。

1 个答案:

答案 0 :(得分:1)

您可以在单个id_of_b值中组合xml的所有类别,然后在列中显示类别。像这样的东西。

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)

已更新问题的更新答案

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)