求将单列多行表变成多列少行表的sql 语句

时间:2021-11-30 17:48:57
我是一个sql初学者,想把一个类似如下的表
单列表A:
a
b
c
d
e
f
g
h
改成三列表B:
a  d  g
b  e  h
c  f

恳请各位前辈给指点一下

12 个解决方案

#1


是不是这样:

select C.* , D.* , E.* FROM (SELECT TOP 3 FROM A) C , (SELECT TOP 3 FROM (SELECT TOP 6 FROM A) ORDER BY A的列名 DESC) D , (SELECT TOP 2 FROM (SELECT * FROM A) ORDER BY A的列名 DESC) E

我也是初学者。

#2


create table #t (id int identity, m char(1));
insert into #t select 'a'
union all select 'b'
union all select 'c'
union all select 'd'
union all select 'e'
union all select 'f'
union all select 'g'
union all select 'h' 

--执行
select m,case id when 1 then isnull((select m from #t where id = t.id + 3),'')
when 2 then isnull((select  m  from #t where id = t.id + 3),'')
when 3 then isnull((select  m  from #t where id = t.id + 3),'') end ,
case id when 1 then isnull((select  m  from #t where id = t.id + 6),'')
when 2 then isnull((select  m  from #t where id = t.id + 6),'')
when 3 then isnull((select  m  from #t where id = t.id + 6),'') end
from #t t
where id <=3

#3



有点意思,这个方法有点笨

declare @列表A table([col] nvarchar(1))
Insert @列表A
select N'a' union all
select N'b' union all
select N'c' union all
select N'd' union all
select N'e' union all
select N'f' union all
select N'g' union all
select N'h'
 
Select id=identity(int,1,1),* into #t from @列表A

select col1,col2,col3 from 
(select id,col col1 from #t where (id-1)/3=0) a  left join
(select id,col col2 from #t where (id-1)/3=1) b on a.id=b.id-3 left join
(select id,col col3 from #t where (id-1)/3=2) c on a.id=c.id-6

a d g
b e h
c f NULL



drop table #t

等高手再解答!!

#4


引用 2 楼 ydage 的回复:
create table #t (id int identity, m char(1)); 
insert into #t select 'a' 
union all select 'b' 
union all select 'c' 
union all select 'd' 
union all select 'e' 
union all select 'f' 
union all select 'g' 
union all select 'h' 

--执行 
select m,case id when 1 then isnull((select m from #t where id = t.id + 3),'') 
when 2 then isnull((select  m  from #t where id = t.id + 3),'') 
whe…


学习

#5


先谢谢大家。可是我要是有个几百行甚至上千行的单列表想改成多列表怎么办啊?

#6


if object_id('tb') is not null
drop table tb
go
create table tb(col varchar(5))
insert into tb select 'a'
insert into tb select 'b'
insert into tb select 'c'
insert into tb select 'd'
insert into tb select 'e'
insert into tb select 'f'
insert into tb select 'g'
insert into tb select 'h'

select px=identity(int,0,1),px2=null,* into # from tb

declare @sql varchar(8000)
select @sql=isnull(@sql+',','')+'max(case when px2='''+ltrim(px2)+''' then ltrim(col) else '''' end) as [col'+ltrim(px2)+']'
from (select distinct px2=(select count(1) from # where px%3*3=t.px%3*3 and col<=t.col) from # t)t
exec('select '+@sql+' from (select px%3*3 as px,px2=(select count(1) from # where px%3*3=t.px%3*3 and col<=t.col),col from # t)t group by px')


col1 col2 col3
a d g
b e h
c f

#7


变3行的算法

#8


if object_id('tb') is not null
drop table tb
go
create table tb(col varchar(5))
insert into tb select 'a'
insert into tb select 'b'
insert into tb select 'c'
insert into tb select 'd'
insert into tb select 'e'
insert into tb select 'f'
insert into tb select 'g'
insert into tb select 'h'
insert into tb select 'i'
insert into tb select 'z'
insert into tb select 'k'
insert into tb select 'l'
insert into tb select 'm'
insert into tb select 'n'
drop table #
select px=identity(int,0,1),px2=null,* into # from tb

declare @sql varchar(8000)
select @sql=isnull(@sql+',','')+'max(case when px='''+ltrim(px)+''' then ltrim(col) else '''' end) as [col'+ltrim(px)+']'
from (select distinct px%3 as px from # t)t
exec('select '+@sql+' from (select px%3 as px,px2=(select count(1) from # where px%3=t.px%3 and col<=t.col),col from # t)t group by px2')


col0 col1 col2
a b c
d e f
g h i
m k l
z n

3列

#9


LS的强悍!!

#10


if object_id('tb') is not null
drop table tb
go
create table tb(col varchar(5))
insert into tb select 'a'
insert into tb select 'b'
insert into tb select 'c'
insert into tb select 'd'
insert into tb select 'e'
insert into tb select 'f'
insert into tb select 'g'
insert into tb select 'h'
insert into tb select 'i'
insert into tb select 'z'
insert into tb select 'k'
insert into tb select 'l'
insert into tb select 'm'
insert into tb select 'n'
drop table #
select px=identity(int,0,1),px2=null,* into # from tb

declare @sql varchar(8000)
select @sql=isnull(@sql+',','')+'max(case when px='''+ltrim(px)+''' then ltrim(col) else '''' end) as [col'+ltrim(px)+']'
from (select distinct px%3 as px from # t)t
exec('select '+@sql+' from (select px%3 as px,px2=(select count(1) from # where px%3=t.px%3 and col<=t.col),col from # t)t group by px2')

-----
Good!

#11




create table tb(id int identity(0,1), col varchar(5))
insert into tb select 'a'
insert into tb select 'b'
insert into tb select 'c'
insert into tb select 'd'
insert into tb select 'e'
insert into tb select 'f'
insert into tb select 'g'
insert into tb select 'h'
insert into tb select 'i'
insert into tb select 'z'
insert into tb select 'k'
insert into tb select 'l'
insert into tb select 'm'
insert into tb select 'n'

select *,id/3 as sign1,id%3 as sign2 into # from tb 

declare @s varchar(1000)
select @s='select sign2 '
select @s=@s+',max(case when ltrim(sign1)='''+ltrim(sign1)+''' then col end) as '''+ltrim(sign1)+''''
from # group by sign1 
select @s=@s+' from # group by sign2'
exec(@s)

/*
sign2       0     1     2     3     4     
----------- ----- ----- ----- ----- ----- 
0           a     d     g     z     m
1           b     e     h     k     n
2           c     f     i     l     NULL

警告: 聚合或其它 SET 操作消除了空值。
*/

#12


还请教 单列540行变 10列60行 怎么写啊!谢谢!

#1


是不是这样:

select C.* , D.* , E.* FROM (SELECT TOP 3 FROM A) C , (SELECT TOP 3 FROM (SELECT TOP 6 FROM A) ORDER BY A的列名 DESC) D , (SELECT TOP 2 FROM (SELECT * FROM A) ORDER BY A的列名 DESC) E

我也是初学者。

#2


create table #t (id int identity, m char(1));
insert into #t select 'a'
union all select 'b'
union all select 'c'
union all select 'd'
union all select 'e'
union all select 'f'
union all select 'g'
union all select 'h' 

--执行
select m,case id when 1 then isnull((select m from #t where id = t.id + 3),'')
when 2 then isnull((select  m  from #t where id = t.id + 3),'')
when 3 then isnull((select  m  from #t where id = t.id + 3),'') end ,
case id when 1 then isnull((select  m  from #t where id = t.id + 6),'')
when 2 then isnull((select  m  from #t where id = t.id + 6),'')
when 3 then isnull((select  m  from #t where id = t.id + 6),'') end
from #t t
where id <=3

#3



有点意思,这个方法有点笨

declare @列表A table([col] nvarchar(1))
Insert @列表A
select N'a' union all
select N'b' union all
select N'c' union all
select N'd' union all
select N'e' union all
select N'f' union all
select N'g' union all
select N'h'
 
Select id=identity(int,1,1),* into #t from @列表A

select col1,col2,col3 from 
(select id,col col1 from #t where (id-1)/3=0) a  left join
(select id,col col2 from #t where (id-1)/3=1) b on a.id=b.id-3 left join
(select id,col col3 from #t where (id-1)/3=2) c on a.id=c.id-6

a d g
b e h
c f NULL



drop table #t

等高手再解答!!

#4


引用 2 楼 ydage 的回复:
create table #t (id int identity, m char(1)); 
insert into #t select 'a' 
union all select 'b' 
union all select 'c' 
union all select 'd' 
union all select 'e' 
union all select 'f' 
union all select 'g' 
union all select 'h' 

--执行 
select m,case id when 1 then isnull((select m from #t where id = t.id + 3),'') 
when 2 then isnull((select  m  from #t where id = t.id + 3),'') 
whe…


学习

#5


先谢谢大家。可是我要是有个几百行甚至上千行的单列表想改成多列表怎么办啊?

#6


if object_id('tb') is not null
drop table tb
go
create table tb(col varchar(5))
insert into tb select 'a'
insert into tb select 'b'
insert into tb select 'c'
insert into tb select 'd'
insert into tb select 'e'
insert into tb select 'f'
insert into tb select 'g'
insert into tb select 'h'

select px=identity(int,0,1),px2=null,* into # from tb

declare @sql varchar(8000)
select @sql=isnull(@sql+',','')+'max(case when px2='''+ltrim(px2)+''' then ltrim(col) else '''' end) as [col'+ltrim(px2)+']'
from (select distinct px2=(select count(1) from # where px%3*3=t.px%3*3 and col<=t.col) from # t)t
exec('select '+@sql+' from (select px%3*3 as px,px2=(select count(1) from # where px%3*3=t.px%3*3 and col<=t.col),col from # t)t group by px')


col1 col2 col3
a d g
b e h
c f

#7


变3行的算法

#8


if object_id('tb') is not null
drop table tb
go
create table tb(col varchar(5))
insert into tb select 'a'
insert into tb select 'b'
insert into tb select 'c'
insert into tb select 'd'
insert into tb select 'e'
insert into tb select 'f'
insert into tb select 'g'
insert into tb select 'h'
insert into tb select 'i'
insert into tb select 'z'
insert into tb select 'k'
insert into tb select 'l'
insert into tb select 'm'
insert into tb select 'n'
drop table #
select px=identity(int,0,1),px2=null,* into # from tb

declare @sql varchar(8000)
select @sql=isnull(@sql+',','')+'max(case when px='''+ltrim(px)+''' then ltrim(col) else '''' end) as [col'+ltrim(px)+']'
from (select distinct px%3 as px from # t)t
exec('select '+@sql+' from (select px%3 as px,px2=(select count(1) from # where px%3=t.px%3 and col<=t.col),col from # t)t group by px2')


col0 col1 col2
a b c
d e f
g h i
m k l
z n

3列

#9


LS的强悍!!

#10


if object_id('tb') is not null
drop table tb
go
create table tb(col varchar(5))
insert into tb select 'a'
insert into tb select 'b'
insert into tb select 'c'
insert into tb select 'd'
insert into tb select 'e'
insert into tb select 'f'
insert into tb select 'g'
insert into tb select 'h'
insert into tb select 'i'
insert into tb select 'z'
insert into tb select 'k'
insert into tb select 'l'
insert into tb select 'm'
insert into tb select 'n'
drop table #
select px=identity(int,0,1),px2=null,* into # from tb

declare @sql varchar(8000)
select @sql=isnull(@sql+',','')+'max(case when px='''+ltrim(px)+''' then ltrim(col) else '''' end) as [col'+ltrim(px)+']'
from (select distinct px%3 as px from # t)t
exec('select '+@sql+' from (select px%3 as px,px2=(select count(1) from # where px%3=t.px%3 and col<=t.col),col from # t)t group by px2')

-----
Good!

#11




create table tb(id int identity(0,1), col varchar(5))
insert into tb select 'a'
insert into tb select 'b'
insert into tb select 'c'
insert into tb select 'd'
insert into tb select 'e'
insert into tb select 'f'
insert into tb select 'g'
insert into tb select 'h'
insert into tb select 'i'
insert into tb select 'z'
insert into tb select 'k'
insert into tb select 'l'
insert into tb select 'm'
insert into tb select 'n'

select *,id/3 as sign1,id%3 as sign2 into # from tb 

declare @s varchar(1000)
select @s='select sign2 '
select @s=@s+',max(case when ltrim(sign1)='''+ltrim(sign1)+''' then col end) as '''+ltrim(sign1)+''''
from # group by sign1 
select @s=@s+' from # group by sign2'
exec(@s)

/*
sign2       0     1     2     3     4     
----------- ----- ----- ----- ----- ----- 
0           a     d     g     z     m
1           b     e     h     k     n
2           c     f     i     l     NULL

警告: 聚合或其它 SET 操作消除了空值。
*/

#12


还请教 单列540行变 10列60行 怎么写啊!谢谢!