0

我有一个包含以下列的表格:

Name, Img1, Img2

数据快照如下所示:

Stack, lemon.jpg, null
Stack, null, orange.jpg
Stack,plum.jpg, null
Stack,grape.jpg, aubergine.jpg

与每个名称关联的图像数量没有限制。

但是,我想返回前十张图片,如下所示:

select name, img1, img2, img3, img4, img5, img6 ... img10
4

2 回答 2

2

由于表中的数据是非规范化的,我建议先对数据进行反透视,然后应用 PIVOT 函数将值转换回您想要的最终结果。

第一步是将img1img2列取消旋转为多行:

select d.name,
  c.value,
  c.col 
    + cast(row_number() over(partition by d.name 
                             order by d.name) as varchar(10)) new_col
from yourtable d
cross apply
(
  select 'img', img1 union all
  select 'img', img2
) c (col, value);

请参阅演示。unpivot 过程会给你一个结果:

|  NAME |         VALUE | NEW_COL |
-----------------------------------
| Stack |     lemon.jpg |    img1 |
| Stack |        (null) |    img2 |
| Stack |        (null) |    img3 |
| Stack |    orange.jpg |    img4 |
| Stack |      plum.jpg |    img5 |
| Stack |        (null) |    img6 |
| Stack |     grape.jpg |    img7 |
| Stack | aubergine.jpg |    img8 |

然后,您可以将枢轴函数应用于 中的值new_col,该值是使用row_number()按名称分区计算的:

select name, img1, img2, img3, img4, img5,
  img6, img7, img8, img9, img10
from
(
  select d.name,
    c.value,
    c.col 
      + cast(row_number() over(partition by d.name 
                               order by d.name) as varchar(10)) new_col
  from yourtable d
  cross apply
  (
    select 'img', img1 union all
    select 'img', img2
  ) c (col, value)
) src
pivot
(
  max(value)
  for new_col in (img1, img2, img3, img4, img5,
                  img6, img7, img8, img9, img10)
) piv;

请参阅带有演示的 SQL Fiddle

于 2013-07-15T15:13:58.107 回答
1

怎么样,

现在有了工作小提琴

    WITH snapshot(n, name, img1, img2) AS
(
    SELECT TOP 5
                ROW_NUMBER() OVER(ORDER BY Name) n,
                name,
                img1,
                img2
        FROM yourtable
        WHERE name = 'Stack'
        ORDER BY Name    
)
SELECT
             row1.Name,
             row1.Img1,
             row1.Img2,
             row2.Img1 Img3,
             row2.Img2 Img4,
             row3.Img1 Img5,
             row3.Img2 Img6,
             row4.Img1 Img7,
             row4.Img2 Img8,
             row5.Img1 Img9,
             row5.Img2 Img10
    FROM snapshot row1
        LEFT JOIN snapshot row2 ON row2.n = 2
        LEFT JOIN snapshot row3 ON row3.n = 3
        LEFT JOIN snapshot row4 ON row4.n = 4
        LEFT JOIN snapshot row5 ON row5.n = 5
    WHERE row1.n = 1

这通过定义 CTE 来工作,

    SELECT TOP 5
                ROW_NUMBER() OVER(ORDER BY Name) n,
                name,
                img1,
                img2
        FROM yourtable
        WHERE name = 'Stack'
        ORDER BY Name

结果可能是

N  NAME   IMG1       IMG2 
1  Stack  lemon.jpg  (null) 
2  Stack  (null)     orange.jpg 
3  Stack  plum.jpg   (null) 
4  Stack  grape.jpg  aubergine.jpg

然后它选择第一行并为所需的每个后续对执行左自连接。

于 2013-07-15T15:22:42.367 回答