0

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

tblProducts

  • 产品编号
  • 产品名称

tblProductImages

  • 产品编号
  • 图像文件名

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

例如,我想看看:

productID productName imageFilename imageFilename imageFilename

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

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

谢谢

4

3 回答 3

2

您可以将 aPIVOT用于此结果。如果您知道列数,则可以对它们进行硬编码:

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

或者您可以使用动态 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

这两个结果都将与此类似:

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)
于 2012-10-16T14:25:30.440 回答
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
于 2012-10-16T14:10:42.743 回答
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
于 2012-10-16T14:23:31.633 回答