简体   繁体   English

将多个sql行与不同的列组合在一起

[英]combine multiple sql rows with different columns

Okay so say I have something like this: 好的,所以说我有这样的事情:

ID | Name | Address
 1 | Bob  | 123 Fake Street
 1 | Bob  | 221 Other Street

done by doing something like: 通过做类似的事情完成:

select p.ID, p.Name a.Address from People p 
inner join Addresses a on a.OwnerID = p.ID

Is there any way to turn that into 有没有办法把它变成

ID | Name |    Address_1    |     Address_2    | etc...
 1 | Bob  | 123 Fake Street | 221 Other street | etc

I've seen things that do comma separated values in one column but I don't want that I want distinct columns. 我已经看到在一列中用逗号分隔值的东西,但我不希望我想要不同的列。 I am querying this using MSSQL and C# I don't know if that changes anything. 我使用MSSQL和C#查询这个我不知道是否会改变任何东西。 Also this is a made up scenario that is just similar to what I'm doing so the actual structure of the tables can't be changed. 此外,这是一个与我正在做的类似的组合场景,因此无法更改表的实际结构。

Anyone have any suggestions? 有人有什么建议吗?

You can use the PIVOT function to get the result but you will also have to implement using a row_number() so you can convert multiple addresses per person into columns. 您可以使用PIVOT函数来获取结果,但您还必须使用row_number()来实现,这样您就可以将每个人的多个地址转换为列。

If you had a known number of addresses, then you would hard-code the query: 如果您有已知数量的地址,那么您将对查询进行硬编码:

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;

See SQL Fiddle with Demo . 请参阅SQL Fiddle with Demo

But if your case, you will have an unknown number of addresses per person so you will want to use dynamic SQL and place it into a stored procedure to execute: 但是,如果你的情况,你将拥有一个未知数量的地址,因此你将需要使用动态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);

See SQL Fiddle with Demo . 请参阅SQL Fiddle with Demo These both give a result: 这两个都给出了结果:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM