Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/76.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL将行重塑为列_Sql_Sql Server - Fatal编程技术网

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顺序并不重要,可以是任何顺序