用不同的列组合多个SQL行
本文关键字:SQL 组合 | 更新日期: 2023-09-27 18:18:27
好的,我们输入如下内容:
ID | Name | Address
1 | Bob | 123 Fake Street
1 | Bob | 221 Other Street
可以这样做:
select p.ID, p.Name a.Address from People p
inner join Addresses a on a.OwnerID = p.ID
有没有办法把它变成
ID | Name | Address_1 | Address_2 | etc...
1 | Bob | 123 Fake Street | 221 Other street | etc
我见过在一列中使用逗号分隔值的情况,但我不想这样,我想要不同的列。我正在使用MSSQL和c#查询这个,我不知道这是否改变了什么。此外,这是一个虚构的场景,与我正在做的类似,因此表的实际结构无法更改。
谁有什么建议?您可以使用PIVOT函数来获得结果,但您也必须使用row_number()
来实现,以便您可以将每个人的多个地址转换为列。
如果您有一个已知的地址数目,那么您将硬编码查询:
select id, name, address_1, address_2
from
(
select p.id, p.name, a.address,
'Address_'+cast(row_number() over(partition by p.id
order by a.ownerid) as varchar(10)) rn
from people p
inner join addresses a
on p.id = a.ownerid
) d
pivot
(
max(address)
for rn in (address_1, address_2)
) piv;
参见SQL Fiddle with Demo。
但是,如果您的情况是,每个人的地址数量未知,那么您将希望使用动态SQL并将其放入存储过程中执行:
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT distinct ',' + QUOTENAME('Address_'+d.rn)
from
(
select cast(row_number() over(partition by a.ownerid
order by a.ownerid) as varchar(10)) rn
from Addresses a
) d
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT id, name, ' + @cols + '
from
(
select p.id, p.name, a.address,
''Address_''+cast(row_number() over(partition by p.id
order by a.ownerid) as varchar(10)) rn
from people p
inner join addresses a
on p.id = a.ownerid
) d
pivot
(
max(address)
for rn in (' + @cols + ')
) p '
execute(@query);
参见SQL Fiddle with Demo。它们都给出了一个结果:
| ID | NAME | ADDRESS_1 | ADDRESS_2 | ADDRESS_3 |
----------------------------------------------------------------
| 1 | Bob | 123 Fake Street | 221 Other Street | (null) |
| 2 | Jim | 123 e main street | (null) | (null) |
| 3 | Tim | 489 North Drive | 56 June Street | 415 Lost |