SQL多个表合为一体

时间:2012-10-16 13:46:30

标签: sql sql-server-2008

我有一个产品表和一个单独的图像表,适用于任何特定产品。

tblProducts

  • 的productID
  • 产品名称

tblProductImages

  • 的productID
  • 映像文件名称

我可以通过两个单独的查询返回产品详细信息,然后返回该产品的产品图片,但我不确定如何将其放入一个查询中?

例如,我想看看:

productID productName imageFilename imageFilename imageFilename

作为我的结果集(需要是动态的,因为每个产品可以上传1到10张图片)。

这是我可以用PIVOT做的事吗?

由于

3 个答案:

答案 0 :(得分: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)

答案 1 :(得分:0)

也尝试这样。每个产品ID都有逗号分隔的文件名。

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

答案 2 :(得分:0)

我想赞扬@RomanParker。但是,当更常见的apply完全足够时,使用join时我感到很不舒服。查询还有许多其他更改,特别是在加入产品表之前聚合

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