2013-07-15 92 views
0

我有以下的列的表列:SQL重塑行

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 
+2

也許你應該重新設計你的數據庫模式。爲什麼你想要列中的數據,它似乎是稀疏的和無限的。 – Jodrell

+0

@Jodrell L E G A C Y – NimChimpsky

+0

什麼版本的sql server? – Taryn

回答

2

因爲在你的表中的數據規格化,我建議首先unpivoting的數據,然後應用PIVOT函數的值轉換回到你想要的最終結果。

的第一步是UNPIVOT的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); 

參見Demo。在逆透視過程中會給你一個結果:

| 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 with Demo

1

怎麼樣,

Now with working fiddle

其中
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 

然後選擇第一行,並沒有左自聯接每個隨後的一對是必需的。