SQL Group By Join

时间:2013-07-22 21:11:46

标签: sql sql-server join group-by

我需要加入三个表来说明产品需要哪些文档。并非所有产品都需要所有文件。

有一个Document表,一个Product表和一个跟踪与产品相关的文档的DocTracking表

Product Table
ProdID   ProdName
1        Ball
2        Wheel
DocTracking Table
ProdID     DocID
1          1
1          2
2          2

我希望联接看起来像这样:

ProdID     ProdName   Needs Word Doc?    Needs Excel Doc?
1          Ball       Yes                Yes
2          Wheel      No                 Yes

如果我需要将其转换为存储过程,那么任何帮助都会受到赞赏,这很好。

4 个答案:

答案 0 :(得分:1)

如果您只有这些文件并且已修复,则可以使用此查询:

SELECT ProdID, ProdName,      
       [Needs Word Doc] = CASE WHEN EXISTS(
           SELECT 1 FROM Document  d INNER JOIN DocTracking dt ON d.DocID=dt.DocID
           WHERE dt.ProdID = p.ProdID AND d.[Doc Name] = 'Word Document'
       ) THEN 'Yes' ELSE 'No' END,
       [Needs Excel Doc] = CASE WHEN EXISTS(
           SELECT 1 FROM Document  d INNER JOIN DocTracking dt ON d.DocID=dt.DocID
           WHERE dt.ProdID = p.ProdID AND d.[Doc Name] = ' Excel Spreadsheet'
       ) THEN 'Yes' ELSE 'No' END
FROM dbo.Product  p

当然您也可以使用DocID,然后查询不依赖于名称。

答案 1 :(得分:1)

select P.ProdID, P.ProdName, 
       case 
          when DW.DocID is null then 'Yes'
          else 'No' 
       end as NeedsWordDoc,    
       case 
          when DE.DocID is null then 'Yes'
          else 'No' 
       end as NeedsExcelDoc
from Product P
left join DocTracking DTW on DTW.ProdId = P.ProdId
left join Document DW on DW.DocID = DTW.DocID
                          and DW.Name = 'Word Document'
left join DocTracking DTE on DTE.ProdId = P.ProdId
left join Document DE on DE.DocID = DTE.DocID
                          and DE.Name = 'Excel Spreadsheet'

答案 2 :(得分:1)

这比典型的数据透视查询要复杂一些。但是,唯一具有挑战性的部分是确定包含哪些文档,然后获取'Yes''No'

以下使用coalesce()执行此操作,并检查是否存在一种类型的文档:

select pt.ProdId, pt.ProdName,
       coalesce(MAX(case when dt.DocId = 1 then 'Yes' end), 'No') as "Needs Word Doc?",
       coalesce(MAX(case when dt.DocId = 2 then 'Yes' end), 'No') as "Needs Excel Doc?"
from ProductTable pt left outer join
     DocTracking dt 
     on dt.ProdId = dt.ProdId
group by pt.ProdId, pt.ProdName;

请注意,SQL查询返回固定数量的列。因此,您不能拥有一个SQL查询,它只根据文档表中的内容返回不同数量的列。您可以在字符串中创建 SQL查询,然后使用特定于数据库的命令来运行它。

答案 3 :(得分:0)

可能会帮助你 - 使用pivot:

select ProdId, ProdName, 
case when isnull([Word Document],0)<>0 then 'Yes'
else 'No' 
end as  [Needs Word Doc?],
case when isnull([Excel Spreadsheet],0)<>0 then 'Yes'
else 'No' 
end as  [Needs Excel Spreadsheet?]
 from
(
select p.ProdId,p.ProdName,d.DocId,d.DocName from 
@Prod p left join 
@Track t
on p.ProdId=t.ProdId 
inner join @Doc d
on t.DocId=d.DocId
)
as temp
pivot
(max(DocID)
For DocName in ([Word Document],[Excel Spreadsheet])
)
as pvt