2014-12-03 85 views
-1

我有这个简化的表结构:显示为相关实体多行结果在一行

enter image description here

如果我做了此标准查询

SELECT p.Name as ProductName, ppl.Name as PersonName, pp.[Priority] 
FROM Product p 
    INNER JOIN ProductPeople pp ON pp.IdProduct = p.Id 
    INNER JOIN People ppl ON pp.IdPerson = ppl.Id 

我得到这样的结果:

enter image description here

不过,我想有这样的结果:

enter image description here

,这是什么查询?

谢谢!

+0

谷歌SQL PIVOT。 – 2014-12-03 15:16:37

+1

@TabAlleman感谢downvote和非常有见地的评论。 – ibiza 2014-12-03 15:20:46

+0

@TabAlleman虽然在概念上这是重要的,但并不需要像PIVOTs最适合聚合。这是当前行的多个引用的简单问题。我不认为这个问题,即使是相当基本的,也值得赞同(因为选票和评论之间没有直接关系,所以这个问题不针对你)。 – 2014-12-03 15:23:28

回答

1

你需要从ProductPeople INNER JOIN People两次选择,让他们在同一行:

SELECT p.Name as [ProductName], 
     ppl1.Name as [PersonPriority1], 
     ppl2.Name as [PersonPriority2] 
FROM Product p 
INNER JOIN ProductPeople pp1 
     ON pp1.IdProduct = p.Id 
     AND pp1.[Priority] = 1 
INNER JOIN People ppl1 
     ON pp1.IdPerson = ppl1.Id 
INNER JOIN ProductPeople pp2 
     ON pp2.IdProduct = p.Id 
     AND pp2.[Priority] = 2 
INNER JOIN People ppl2 
     ON pp2.IdPerson = ppl2.Id; 

上述假设总是会有一个优先级2人。如果该假设无效,并且有ProductPeople记录没有分配Priority2 Person,则会过滤掉整行。在这种情况下,你在第二参考需要LEFT JOIN

SELECT p.Name as [ProductName], 
     ppl1.Name as [PersonPriority1], 
     ppl2.Name as [PersonPriority2] 
FROM Product p 
INNER JOIN ProductPeople pp1 
     ON pp1.IdProduct = p.Id 
     AND pp1.[Priority] = 1 
INNER JOIN People ppl1 
     ON pp1.IdPerson = ppl1.Id 
LEFT JOIN (
       ProductPeople pp2 
    INNER JOIN People ppl2 
      ON pp2.IdPerson = ppl2.Id 
     ) 
     ON pp2.IdProduct = p.Id 
     AND pp2.[Priority] = 2; 
1

尝试以下操作:

declare @product table (Id int, Name varchar(100)) 
insert into @product select 1, 'Product 1' union select 2, 'Product 2' 

declare @ProductPeople table(IdProduct int, IdPerson int, Priority int) 
insert into @ProductPeople 
select 1, 1, 1 union select 1, 2, 2 union select 2, 1, 1 union select 2, 2, 2 

declare @People table(Id int, Name varchar(100)) 
insert into @People select 1, 'Person1' union select 2, 'Person2' 

select ProductName, [1] 'PersonPriority1', [2] 'PersonPriority2' 
from 
(
select pd.Name as ProductName, ppl.Name, pp.Priority from @People ppl 
join @ProductPeople pp on pp.IdPerson = ppl.Id 
join @product pd on pd.Id = pp.IdProduct 
)t 
pivot 
(
max(Name) for priority in ([1], [2]))pvt