SQL将行重塑为列
我有一个包含以下列的表:SQL将行重塑为列,sql,sql-server,Sql,Sql Server,我有一个包含以下列的表: 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 由于表中的数据是非规范化的
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
由于表中的数据是非规范化的,因此我建议先取消激活数据,然后应用PIVOT函数将值转换回所需的最终结果 第一步是将
img1
和img2
列解压为多行:
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);
看。取消PIVOT过程将为您提供一个结果:
| 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 |
然后,您可以将pivot函数应用于new\u col
中的值,该值是使用按名称划分的row\u 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;
请参见由于表中的数据是非规范化的,因此我建议先取消对数据的激励,然后应用PIVOT函数将值转换回所需的最终结果 第一步是将
img1
和img2
列解压为多行:
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);
看。取消PIVOT过程将为您提供一个结果:
| 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 |
然后,您可以将pivot函数应用于new\u col
中的值,该值是使用按名称划分的row\u 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;
请参见
这通过定义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
然后,它选择第一行,并对所需的每个后续对进行左自联接。
这通过定义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
然后,它选择第一行,并对所需的每个后续对进行左自联接。也许您应该重新设计数据库架构。为什么要将数据放在列中,因为它似乎是稀疏填充和无限的。sql server的哪个版本?请参阅问题:如何在快照中对数据排序?是什么使得
lemon.jpg,null
出现在null,orange.jpg
之前?@Jodrell顺序并不重要,可以是任何顺序也许您应该重新设计数据库架构。为什么要将数据放在列中,因为它似乎是稀疏填充和无限的。sql server的哪个版本?请参阅问题:如何在快照中对数据排序?是什么使得lemon.jpg,null
出现在null,orange.jpg
之前?@Jodrell顺序并不重要,可以是任何顺序