将一个表中的多行合并到SQL查询结果集中的多个列中
我正在为一份新报告做一个基本的查询,遇到了这个小问题 我有两个表将一个表中的多行合并到SQL查询结果集中的多个列中,sql,sql-server,pivot,Sql,Sql Server,Pivot,我正在为一份新报告做一个基本的查询,遇到了这个小问题 我有两个表建筑物(B)和图片(p)。两个表中的关键是建筑物编号。我在两个表之间有一个简单的内部连接。我遇到的问题是,我有183栋建筑在B区,但每栋建筑都有多张图片,而且每栋建筑的图片数量并不一致。因此,当我得到结果集时,它将返回大约260行。我想做的是为每个建筑返回一行,并为每个与该建筑相关联的图片创建一列。请记住,我无权更改或创建表 我的数据如下: BuildingNumber BldgName Floors SqFt Pi
建筑物
(B)和图片
(p)。两个表中的关键是建筑物编号。我在两个表之间有一个简单的内部连接。我遇到的问题是,我有183栋建筑在B区,但每栋建筑都有多张图片,而且每栋建筑的图片数量并不一致。因此,当我得到结果集时,它将返回大约260行。我想做的是为每个建筑返回一行,并为每个与该建筑相关联的图片创建一列。请记住,我无权更改或创建表
我的数据如下:
BuildingNumber BldgName Floors SqFt PictureURL1 PictureURL2 PictureURL3
0001 Science 5 50000 URL1 URL2 URL3
0002 Engineering 4 40000 URL1 URL2 NULL
建筑表(B):
图片表(p):
因此,我期望的结果如下所示:
BuildingNumber BldgName Floors SqFt PictureURL1 PictureURL2 PictureURL3
0001 Science 5 50000 URL1 URL2 URL3
0002 Engineering 4 40000 URL1 URL2 NULL
您可以使用该函数获取结果,该函数将数据行转换为列
如果每个建筑的PictureURLs
数量有限,则可以对查询进行硬编码:
select BuildingNumber, bldgname, floors, sqft,
PictureURL1, PictureURL2, PictureURL3
from
(
select b.BuildingNumber, b.bldgname, b.floors, b.sqft,
p.PictureURL,
col = 'PictureURL'+
cast(row_number() over(partition by b.BuildingNumber
order by b.BuildingNumber) as varchar(10))
from building b
inner join picture p
on b.BuildingNumber = p.BuildingNumber
) d
pivot
(
max(PictureURL)
for col in (PictureURL1, PictureURL2, PictureURL3)
) piv;
看。但是如果您有未知数量的值,那么您必须考虑使用动态SQL。这将创建一个sql字符串,将执行该字符串以获得最终结果:
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT distinct ',' + QUOTENAME('PictureURL'+
cast(row_number() over(partition by BuildingNumber
order by BuildingNumber) as varchar(10)))
from Picture
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT BuildingNumber, bldgname, floors, sqft,' + @cols + '
from
(
select b.BuildingNumber, b.bldgname, b.floors, b.sqft,
p.PictureURL,
col = ''PictureURL''+
cast(row_number() over(partition by b.BuildingNumber
order by b.BuildingNumber) as varchar(10))
from building b
inner join picture p
on b.BuildingNumber = p.BuildingNumber
) x
pivot
(
max(PictureURL)
for col in (' + @cols + ')
) p '
execute sp_executesql @query;
看。两者都给出了一个结果:
| BUILDINGNUMBER | BLDGNAME | FLOORS | SQFT | PICTUREURL1 | PICTUREURL2 | PICTUREURL3 |
| 1 | Science | 5 | 50000 | URL1 | URL2 | URL3 |
| 2 | Engineering | 4 | 40000 | URL1 | URL2 | (null) |
您可以使用该函数获取结果,该函数将数据行转换为列
如果每个建筑的PictureURLs
数量有限,则可以对查询进行硬编码:
select BuildingNumber, bldgname, floors, sqft,
PictureURL1, PictureURL2, PictureURL3
from
(
select b.BuildingNumber, b.bldgname, b.floors, b.sqft,
p.PictureURL,
col = 'PictureURL'+
cast(row_number() over(partition by b.BuildingNumber
order by b.BuildingNumber) as varchar(10))
from building b
inner join picture p
on b.BuildingNumber = p.BuildingNumber
) d
pivot
(
max(PictureURL)
for col in (PictureURL1, PictureURL2, PictureURL3)
) piv;
看。但是如果您有未知数量的值,那么您必须考虑使用动态SQL。这将创建一个sql字符串,将执行该字符串以获得最终结果:
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT distinct ',' + QUOTENAME('PictureURL'+
cast(row_number() over(partition by BuildingNumber
order by BuildingNumber) as varchar(10)))
from Picture
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT BuildingNumber, bldgname, floors, sqft,' + @cols + '
from
(
select b.BuildingNumber, b.bldgname, b.floors, b.sqft,
p.PictureURL,
col = ''PictureURL''+
cast(row_number() over(partition by b.BuildingNumber
order by b.BuildingNumber) as varchar(10))
from building b
inner join picture p
on b.BuildingNumber = p.BuildingNumber
) x
pivot
(
max(PictureURL)
for col in (' + @cols + ')
) p '
execute sp_executesql @query;
看。两者都给出了一个结果:
| BUILDINGNUMBER | BLDGNAME | FLOORS | SQFT | PICTUREURL1 | PICTUREURL2 | PICTUREURL3 |
| 1 | Science | 5 | 50000 | URL1 | URL2 | URL3 |
| 2 | Engineering | 4 | 40000 | URL1 | URL2 | (null) |
为了澄清这个问题,您希望在行的末尾有一个动态的列数?正确。我不知道每个建筑有多少张图片。最好是执行2个查询,在程序中可以匹配图片和建筑。为了澄清问题,您希望在行的末尾有动态的列数?正确。我真的不知道每个建筑有多少张图片。最好是执行2个查询,在你的程序中,你可以匹配图片和建筑。单引号应该在那里吗?我尝试了带和不带,但仍然没有得到结果集。@Jake哪个单引号?为了澄清,在“set@query=“@Jake”后面的SELECT前面,set查询正在创建一个sql字符串,因此单引号必须存在。谢谢先生。我真的很感谢你在这方面的帮助。我运行了第二个查询并提取了我需要的所有相关数据。单引号应该在那里吗?我尝试了带和不带,但仍然没有得到结果集。@Jake哪个单引号?为了澄清,在“set@query=“@Jake”后面的SELECT前面,set查询正在创建一个sql字符串,因此单引号必须存在。谢谢先生。我真的很感谢你在这方面的帮助。我运行了第二个查询,并提取了我需要的所有相关数据。