0

製品の表と、特定の製品の画像の別の表があります。

tblProducts

  • 製品番号
  • 商品名

tblProductImages

  • 製品番号
  • imageFileName

2つの個別のクエリを使用して、商品の詳細とその商品の商品画像を返すことができますが、1つのクエリにまとめる方法がわかりません。

たとえば、私は見たいと思います:

productID productName imageFilename imageFilename imageFilename

私の結果セットとして(製品ごとに1から10の画像がアップロードされる可能性があるため、動的である必要があります)。

これは私がPIVOTでできることですか?

ありがとう

4

3 に答える 3

2

PIVOTこの結果には a を使用できます。列の数がわかっている場合は、それらをハードコーディングできます。

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 に答える