多行转换成一行多列

时间:2020-12-21 10:52:00
表a:
id  bindid   name     
1    1          wang
2    2          zhang
表b:
id    bindid    address
1        1           aaa
2        1           bbb
3        2           ccc
4        2           ddd
想实现的效果:
bindid    name    address1    address2
1             wang     aaa               bbb
2            zhang     ccc               ddd
请大神帮忙解答

4 个解决方案

#1


----------------------------------------------------------------
-- Author  :DBA_HuangZJ(發糞塗牆)
-- Date    :2014-09-04 15:12:17
-- Version:
--      Microsoft SQL Server 2012 - 11.0.5058.0 (X64) 
-- May 14 2014 18:34:29 
-- Copyright (c) Microsoft Corporation
-- Enterprise Edition: Core-based Licensing (64-bit) on Windows NT 6.3 <X64> (Build 9600: ) (Hypervisor)
--
----------------------------------------------------------------
--> 测试数据:[A]
if object_id('[A]') is not null drop table [A]
go 
create table [A]([id] int,[bindid] int,[name] varchar(5))
insert [A]
select 1,1,'wang' union all
select 2,2,'zhang'
--> 测试数据:[B]
if object_id('[B]') is not null drop table [B]
go 
create table [B]([id] int,[bindid] int,[address] varchar(3))
insert [B]
select 1,1,'aaa' union all
select 2,1,'bbb' union all
select 3,2,'ccc' union all
select 4,2,'ddd'
--------------开始查询--------------------------

select a.id,a.bindid,a.NAME,MAX(CASE WHEN b.id2=1 THEN ADDRESS ELSE NULL END )[address1],MAX(CASE WHEN b.id2=2 THEN ADDRESS ELSE NULL END )[address2]
from [A] a LEFT JOIN (SELECT *,ROW_NUMBER()OVER(PARTITION BY bindid ORDER BY id)id2 FROM [b]) [b] ON a.bindid=b.bindid
GROUP BY a.id,a.bindid,a.NAME
----------------结果----------------------------
/* 
id          bindid      NAME  address1 address2
----------- ----------- ----- -------- --------
1           1           wang  aaa      bbb
2           2           zhang ccc      ddd
*/

#2


1楼是静态的,这是动态的
----------------------------------------------------------------
-- Author  :DBA_HuangZJ(發糞塗牆)
-- Date    :2014-09-04 15:12:17
-- Version:
--      Microsoft SQL Server 2012 - 11.0.5058.0 (X64) 
-- May 14 2014 18:34:29 
-- Copyright (c) Microsoft Corporation
-- Enterprise Edition: Core-based Licensing (64-bit) on Windows NT 6.3 <X64> (Build 9600: ) (Hypervisor)
--
----------------------------------------------------------------
--> 测试数据:[A]
if object_id('[A]') is not null drop table [A]
go 
create table [A]([id] int,[bindid] int,[name] varchar(5))
insert [A]
select 1,1,'wang' union all
select 2,2,'zhang'
--> 测试数据:[B]
if object_id('[B]') is not null drop table [B]
go 
create table [B]([id] int,[bindid] int,[address] varchar(3))
insert [B]
select 1,1,'aaa' union all
select 2,1,'bbb' union all
select 3,2,'ccc' union all
select 4,2,'ddd'
--------------开始查询--------------------------

--select a.id,a.bindid,a.NAME,MAX(CASE WHEN b.id2=1 THEN ADDRESS ELSE NULL END )[address1],MAX(CASE WHEN b.id2=2 THEN ADDRESS ELSE NULL END )[address2]
--from [A] a LEFT JOIN (SELECT *,ROW_NUMBER()OVER(PARTITION BY bindid ORDER BY id)id2 FROM [b]) [b] ON a.bindid=b.bindid
--GROUP BY a.id,a.bindid,a.NAME
IF OBJECT_ID('tempdb..#t','u') IS NOT NULL 
DROP TABLE #t
SELECT a.*,b.ADDRESS,b.id2 INTO #t
from [A] a LEFT JOIN (SELECT *,ROW_NUMBER()OVER(PARTITION BY bindid ORDER BY id)id2 FROM [b]) [b] ON a.bindid=b.bindid

declare @s nvarchar(4000)
set @s=''
Select     @s=@s+','+quotename('address'+CAST(ROW_NUMBER()OVER(ORDER BY GETDATE())AS VARCHAR(2))  )+'=max(case when [id2]='+quotename(id2,'''')+' then [ADDRESS] else null end)'
from #t group by id2
exec('select id,bindid,name'+@s+' from #t group by id,bindid,name')
----------------结果----------------------------
/* 
id          bindid      name  address1 address2
----------- ----------- ----- -------- --------
1           1           wang  aaa      bbb
2           2           zhang ccc      ddd
*/

#3


引用 1 楼 DBA_Huangzj 的回复:
----------------------------------------------------------------
-- Author  :DBA_HuangZJ(發糞塗牆)
-- Date    :2014-09-04 15:12:17
-- Version:
--      Microsoft SQL Server 2012 - 11.0.5058.0 (X64) 
-- May 14 2014 18:34:29 
-- Copyright (c) Microsoft Corporation
-- Enterprise Edition: Core-based Licensing (64-bit) on Windows NT 6.3 <X64> (Build 9600: ) (Hypervisor)
--
----------------------------------------------------------------
--> 测试数据:[A]
if object_id('[A]') is not null drop table [A]
go 
create table [A]([id] int,[bindid] int,[name] varchar(5))
insert [A]
select 1,1,'wang' union all
select 2,2,'zhang'
--> 测试数据:[B]
if object_id('[B]') is not null drop table [B]
go 
create table [B]([id] int,[bindid] int,[address] varchar(3))
insert [B]
select 1,1,'aaa' union all
select 2,1,'bbb' union all
select 3,2,'ccc' union all
select 4,2,'ddd'
--------------开始查询--------------------------

select a.id,a.bindid,a.NAME,MAX(CASE WHEN b.id2=1 THEN ADDRESS ELSE NULL END )[address1],MAX(CASE WHEN b.id2=2 THEN ADDRESS ELSE NULL END )[address2]
from [A] a LEFT JOIN (SELECT *,ROW_NUMBER()OVER(PARTITION BY bindid ORDER BY id)id2 FROM [b]) [b] ON a.bindid=b.bindid
GROUP BY a.id,a.bindid,a.NAME
----------------结果----------------------------
/* 
id          bindid      NAME  address1 address2
----------- ----------- ----- -------- --------
1           1           wang  aaa      bbb
2           2           zhang ccc      ddd
*/


bindid的值不固定呢,有好多,这种情况怎么查

#4


用2楼的动态

#1


----------------------------------------------------------------
-- Author  :DBA_HuangZJ(發糞塗牆)
-- Date    :2014-09-04 15:12:17
-- Version:
--      Microsoft SQL Server 2012 - 11.0.5058.0 (X64) 
-- May 14 2014 18:34:29 
-- Copyright (c) Microsoft Corporation
-- Enterprise Edition: Core-based Licensing (64-bit) on Windows NT 6.3 <X64> (Build 9600: ) (Hypervisor)
--
----------------------------------------------------------------
--> 测试数据:[A]
if object_id('[A]') is not null drop table [A]
go 
create table [A]([id] int,[bindid] int,[name] varchar(5))
insert [A]
select 1,1,'wang' union all
select 2,2,'zhang'
--> 测试数据:[B]
if object_id('[B]') is not null drop table [B]
go 
create table [B]([id] int,[bindid] int,[address] varchar(3))
insert [B]
select 1,1,'aaa' union all
select 2,1,'bbb' union all
select 3,2,'ccc' union all
select 4,2,'ddd'
--------------开始查询--------------------------

select a.id,a.bindid,a.NAME,MAX(CASE WHEN b.id2=1 THEN ADDRESS ELSE NULL END )[address1],MAX(CASE WHEN b.id2=2 THEN ADDRESS ELSE NULL END )[address2]
from [A] a LEFT JOIN (SELECT *,ROW_NUMBER()OVER(PARTITION BY bindid ORDER BY id)id2 FROM [b]) [b] ON a.bindid=b.bindid
GROUP BY a.id,a.bindid,a.NAME
----------------结果----------------------------
/* 
id          bindid      NAME  address1 address2
----------- ----------- ----- -------- --------
1           1           wang  aaa      bbb
2           2           zhang ccc      ddd
*/

#2


1楼是静态的,这是动态的
----------------------------------------------------------------
-- Author  :DBA_HuangZJ(發糞塗牆)
-- Date    :2014-09-04 15:12:17
-- Version:
--      Microsoft SQL Server 2012 - 11.0.5058.0 (X64) 
-- May 14 2014 18:34:29 
-- Copyright (c) Microsoft Corporation
-- Enterprise Edition: Core-based Licensing (64-bit) on Windows NT 6.3 <X64> (Build 9600: ) (Hypervisor)
--
----------------------------------------------------------------
--> 测试数据:[A]
if object_id('[A]') is not null drop table [A]
go 
create table [A]([id] int,[bindid] int,[name] varchar(5))
insert [A]
select 1,1,'wang' union all
select 2,2,'zhang'
--> 测试数据:[B]
if object_id('[B]') is not null drop table [B]
go 
create table [B]([id] int,[bindid] int,[address] varchar(3))
insert [B]
select 1,1,'aaa' union all
select 2,1,'bbb' union all
select 3,2,'ccc' union all
select 4,2,'ddd'
--------------开始查询--------------------------

--select a.id,a.bindid,a.NAME,MAX(CASE WHEN b.id2=1 THEN ADDRESS ELSE NULL END )[address1],MAX(CASE WHEN b.id2=2 THEN ADDRESS ELSE NULL END )[address2]
--from [A] a LEFT JOIN (SELECT *,ROW_NUMBER()OVER(PARTITION BY bindid ORDER BY id)id2 FROM [b]) [b] ON a.bindid=b.bindid
--GROUP BY a.id,a.bindid,a.NAME
IF OBJECT_ID('tempdb..#t','u') IS NOT NULL 
DROP TABLE #t
SELECT a.*,b.ADDRESS,b.id2 INTO #t
from [A] a LEFT JOIN (SELECT *,ROW_NUMBER()OVER(PARTITION BY bindid ORDER BY id)id2 FROM [b]) [b] ON a.bindid=b.bindid

declare @s nvarchar(4000)
set @s=''
Select     @s=@s+','+quotename('address'+CAST(ROW_NUMBER()OVER(ORDER BY GETDATE())AS VARCHAR(2))  )+'=max(case when [id2]='+quotename(id2,'''')+' then [ADDRESS] else null end)'
from #t group by id2
exec('select id,bindid,name'+@s+' from #t group by id,bindid,name')
----------------结果----------------------------
/* 
id          bindid      name  address1 address2
----------- ----------- ----- -------- --------
1           1           wang  aaa      bbb
2           2           zhang ccc      ddd
*/

#3


引用 1 楼 DBA_Huangzj 的回复:
----------------------------------------------------------------
-- Author  :DBA_HuangZJ(發糞塗牆)
-- Date    :2014-09-04 15:12:17
-- Version:
--      Microsoft SQL Server 2012 - 11.0.5058.0 (X64) 
-- May 14 2014 18:34:29 
-- Copyright (c) Microsoft Corporation
-- Enterprise Edition: Core-based Licensing (64-bit) on Windows NT 6.3 <X64> (Build 9600: ) (Hypervisor)
--
----------------------------------------------------------------
--> 测试数据:[A]
if object_id('[A]') is not null drop table [A]
go 
create table [A]([id] int,[bindid] int,[name] varchar(5))
insert [A]
select 1,1,'wang' union all
select 2,2,'zhang'
--> 测试数据:[B]
if object_id('[B]') is not null drop table [B]
go 
create table [B]([id] int,[bindid] int,[address] varchar(3))
insert [B]
select 1,1,'aaa' union all
select 2,1,'bbb' union all
select 3,2,'ccc' union all
select 4,2,'ddd'
--------------开始查询--------------------------

select a.id,a.bindid,a.NAME,MAX(CASE WHEN b.id2=1 THEN ADDRESS ELSE NULL END )[address1],MAX(CASE WHEN b.id2=2 THEN ADDRESS ELSE NULL END )[address2]
from [A] a LEFT JOIN (SELECT *,ROW_NUMBER()OVER(PARTITION BY bindid ORDER BY id)id2 FROM [b]) [b] ON a.bindid=b.bindid
GROUP BY a.id,a.bindid,a.NAME
----------------结果----------------------------
/* 
id          bindid      NAME  address1 address2
----------- ----------- ----- -------- --------
1           1           wang  aaa      bbb
2           2           zhang ccc      ddd
*/


bindid的值不固定呢,有好多,这种情况怎么查

#4


用2楼的动态