2012-10-16 163 views
0

我有一个产品表和一个单独的任何特定产品的图像表。将SQL多个表合并为一个

tblProducts

  • 的productID
  • PRODUCTNAME

tblProductImages

  • 的productID
  • 映像文件名称

我可以通过两个单独的查询返回该产品的产品详细信息和产品图像,但我不确定如何将其置于一个查询中?

因此,例如,我想看看:

productID productName imageFilename imageFilename imageFilename 

我的结果集(需要是动态的,因为有可能会从每个产品上传1到10的图像是任何东西)。

这是我能用PIVOT做的事吗?

感谢

+1

你真的想拥有动态数你的结果中的列? –

+1

如果imagefile不存在,那么你的结果中是否有10列固定并保留为空值? – AnandPhadke

+1

我强烈建议或者保留规范化集合(有两个查询)或一个集合(如你所愿),但有固定数量的fileName字段。 – MatBailie

回答

2

可以使用PIVOT这一结果。如果您知道列的数量,那么你可以硬编码它们:

select * 
from 
(
    select p.productid, 
    p.productname, 
    i.imagefilename, 
    'ImageFile_' + 
     cast(row_number() over(partition by i.productid 
       order by i.productid) as varchar(10)) col 
    from tblproducts p 
    left join tblProductImages i 
    on p.productid = i.productid 
) x 
pivot 
(
    max(imagefilename) 
    for col in ([ImageFile_1], [ImageFile_2], [ImageFile_3]) 
) p 

SQL Fiddle with Demo

或者您可以使用动态SQL生成PIVOT。动态会在你有变动数的imagefilename事件工作:

DECLARE @cols AS NVARCHAR(MAX), 
    @query AS NVARCHAR(MAX) 

select @cols = STUFF((SELECT distinct ',' 
         + QUOTENAME('ImageFile_'+ cast(x.rn as varchar(10))) 
        from 
        (
         select row_number() over(partition by i.productid 
          order by i.productid) rn 
         from tblProductImages i 
        ) x 
      FOR XML PATH(''), TYPE 
      ).value('.', 'NVARCHAR(MAX)') 
     ,1,1,'') 

set @query = 'SELECT productid, productname,' + @cols + ' 
       from 
      (
       select p.productid, 
        p.productname, 
        i.imagefilename, 
        ''ImageFile_'' + 
        cast(row_number() over(partition by i.productid 
           order by i.productid) as varchar(10)) col 
       from tblproducts p 
       left join tblProductImages i 
        on p.productid = i.productid 
      ) x 
      pivot 
      (
       max(imagefilename) 
       for col in (' + @cols + ') 
      ) p ' 

execute(@query) 

SQL Fiddle with Demo

两个结果将类似于此:

PRODUCTID | PRODUCTNAME | IMAGEFILE_1 | IMAGEFILE_2 | IMAGEFILE_3 
================================================================== 
1   | Product 1 | Image1  | Image2  | Image3 
2   | Product 2 | Image1  | Image2  | (null) 
3   | Product 3 | Image1  | (null)  | (null) 
4   | Product 4 | Image1  | Image2  | Image3 
5   | Product 5 | Image1  | (null)  | (null) 
0

也试着像this.Just有一个逗号separeted名每个的productID。

select p.productID, 
(select STUFF((select ','+imageFileName from tblProductImages where productID=p.productID 
for xml path('')),1,1,'')) as ImageFileNames 
from tblProducts p 
group by p.productID 
0

我想给@RomanParker。然而,当更常见的join完全足够时,我很难使用apply。还有一些其他的更改查询,特别是聚集之前加入到产品表:

select P.productID, P.productName, 
     imageFileName1, 
     imageFileName2, 
     imageFileName3, 
     ... 
     imageFileName10 
from tblProducts as P left outer join 
    (select I.productID, 
      min(case when I.RowNum = 1 then I.imageFileName else null end) as imageFileName1, 
      min(case when I.RowNum = 2 then I.imageFileName else null end) as imageFileName2, 
      min(case when I.RowNum = 3 then I.imageFileName else null end) as imageFileName3, 
      ... 
      min(case when I.RowNum = 10 then I.imageFileName else null end) as imageFileName10 
     from (select I.*, 
        row_number() over (partition by ProductId Order by (select NULL)) as RowNum 
      from tblProductImages as I 
      ) I 
     group by I.productID 
    ) 
    on p.productId = I.productID