简单的列转行实现

bala7229291 2011-03-24 05:14:09
现有表结构

/*
表结构为:
a
----
A
B
C
D
E
F
G


需要的结果是:
a b c d e f g
---- ---- ---- ---- ---- ---- ----
A B C D E F G
*/
...全文
242 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
zlcqupt 2011-03-31
  • 打赏
  • 举报
回复
学习pivot
So_CooL 2011-03-31
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 xrongzhen 的回复:]
SQL code

use test

if object_id('tb') is not null drop table tb
GO
create table tb(ID int,aa varchar(10))
insert into tb
select 5,'E' union all
select 6,'F' union all
select 3,'C' union a……
[/Quote]
这个通用
tjc_333 2011-03-31
  • 打赏
  • 举报
回复
那样的 行转列太死板 了
bala7229291 2011-03-25
  • 打赏
  • 举报
回复
并且还得满足

/*
表结构为:
ID a
----------- ----
1 E
2 F
3 C
4 D
5 A
6 B
7 G

需要的结果是:
1 2 3 4 5 6 7
---- ---- ---- ---- ---- ---- ----
E F C D A B G


bala7229291 2011-03-25
  • 打赏
  • 举报
回复
还是我没有说清楚,转成的行是有顺序的,按照ID的升序排列的

/*
表结构为:
ID a
----------- ----
5 E
6 F
3 C
4 D
1 A
2 B
7 G

需要的结果是:
1 2 3 4 5 6 7
---- ---- ---- ---- ---- ---- ----
A B C D E F G

xrongzhen 2011-03-25
  • 打赏
  • 举报
回复

use test

if object_id('tb') is not null drop table tb
GO
create table tb(ID int,aa varchar(10))
insert into tb
select 5,'E' union all
select 6,'F' union all
select 3,'C' union all
select 4,'D' union all
select 1,'A' union all
select 2,'B' union all
select 7,'G'

declare @sql varchar(8000)
select @sql = isnull(@sql + '],[' , '') + convert(varchar(10),ID) from tb group by ID
set @sql = '[' + @sql + ']'
exec ('select * from (select * from tb) t pivot (max(aa) for ID in (' + @sql + ')) b')

--查询结果
--1 2 3 4 5 6 7
------------ ---------- ---------- ---------- ---------- ---------- ----------
--A B C D E F G
--
--(1 行受影响)

bluesmiler 2011-03-25
  • 打赏
  • 举报
回复
if object_id('tb') is not null drop table tb
GO
create table tb(ID int ,aa varchar(1))
insert into tb
select 5,'E' union all
select 6,'F' union all
select 3,'C' union all
select 4,'D' union all
select 1,'A' union all
select 2,'B' union all
select 7,'G'

会自动排序的,你也可以加个order by ID指定排序
declare @sql varchar(8000)
select @sql = isnull(@sql + '],[' , '') + cast (id as varchar) from tb group by id order by ID

set @sql = '[' + @sql + ']'

exec ('select * from tb pivot (max(aa) for id in (' + @sql + ')) b')
javatemptation 2011-03-24
  • 打赏
  • 举报
回复

use tempdb;
/*
create table t1
(
ID int not null,
a nvarchar(10) not null
);
insert into t1(ID,a)
values
(1,'A'),
(2,'B'),
(3,'C'),
(4,'D'),
(5,'E'),
(6,'F'),
(7,'G');
*/
select
MAX(case when ID = 1 then 'A' end) as [1],
MAX(case when ID = 2 then 'B' end) as [2],
MAX(case when ID = 3 then 'C' end) as [3],
MAX(case when ID = 4 then 'D' end) as [4],
MAX(case when ID = 5 then 'E' end) as [5],
MAX(case when ID = 6 then 'F' end) as [6],
MAX(case when ID = 7 then 'G' end) as [7]
from t1;
回南山种豆 2011-03-24
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 fredrickhu 的回复:]
SQL code
select
max(case a when 'a' then a else '' end) as a,
max(case a when 'b' then a else '' end) as b,
max(case a when 'c' then a else '' end) as c,
max(case a when 'd' then a el……
[/Quote]

大牛,我随处都见到你的身影
xrongzhen 2011-03-24
  • 打赏
  • 举报
回复

use test

if object_id('tb') is not null drop table tb
GO
create table tb(ID int identity(1,1),aa varchar(1))
insert into tb
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'




declare @sql varchar(8000)
select @sql = isnull(@sql + '],[' , '') + aa from tb group by aa
set @sql = '[' + @sql + ']'
exec ('select * from (select * from tb) t pivot (max(ID) for aa in (' + @sql + ')) b')
bala7229291 2011-03-24
  • 打赏
  • 举报
回复
我看了半天还是没有摸着窍门,还是有点乱,哪位能不能帮我实现一下,我在这个基础上来看看

/*
表结构为:
ID a
----------- ----
1 A
2 B
3 C
4 D
5 E
6 F
7 G

需要的结果是:
1 2 3 4 5 6 7
---- ---- ---- ---- ---- ---- ----
A B C D E F G
*/


快溜 2011-03-24
  • 打赏
  • 举报
回复
看动态行转列部分。
快溜 2011-03-24
  • 打赏
  • 举报
回复
行转列问题总结 - 1、行转列 (后面不断整理论坛中出现的各类问题)

---1、最简单的行转列
/*

问题:假设有张学生成绩表(tb)如下:
姓名 课程 分数
张三 语文 74
张三 数学 83
张三 物理 93
李四 语文 74
李四 数学 84
李四 物理 94


想变成(得到如下结果):
姓名 语文 数学 物理
李四 74 84 94
张三 74 83 93
*/
--测试用
IF OBJECT_ID('[tb]') IS NOT NULL DROP TABLE [tb]
GO
create table tb(姓名 varchar(10) , 课程 varchar(10) , 分数 int)
insert into tb values('张三' , '语文' , 74)
insert into tb values('张三' , '数学' , 83)
insert into tb values('张三' , '物理' , 93)
insert into tb values('李四' , '语文' , 74)
insert into tb values('李四' , '数学' , 84)
insert into tb values('李四' , '物理' , 94)
go

--SQL SERVER 2000 动态SQL,指课程不止语文、数学、物理这三门课程。(以下同)
declare @sql varchar(8000)
set @sql = 'select 姓名 '
select @sql = @sql + ' , max(case 课程 when ''' + 课程 + ''' then 分数 else 0 end) [' + 课程 + ']'
from (select distinct 课程 from tb) as a
set @sql = @sql + ' from tb group by 姓名'
exec(@sql)
--通过动态构建@sql,得到如下脚本
select 姓名 as 姓名 ,
max(case 课程 when '语文' then 分数 else 0 end) 语文,
max(case 课程 when '数学' then 分数 else 0 end) 数学,
max(case 课程 when '物理' then 分数 else 0 end) 物理
from tb
group by 姓名

--SQL SERVER 2005 动态SQL。
declare @sql varchar(8000)
select @sql = isnull(@sql + '],[' , '') + 课程 from tb group by 课程
set @sql = '[' + @sql + ']'
exec ('select * from (select * from tb) a pivot (max(分数) for 课程 in (' + @sql + ')) b')
--得到SQL SERVER 2005 静态SQL。
select * from (select * from tb) a pivot (max(分数) for 课程 in (语文,数学,物理)) b

--查询结果
/*
姓名 数学 物理 语文
---------- ----------- ----------- -----------
李四 84 94 74
张三 83 93 74

(所影响的行数为 2 行)
*/


--2 加合计
/*
问题:在上述结果的基础上加平均分,总分,得到如下结果:
姓名 语文 数学 物理 平均分 总分
---- ---- ---- ---- ------ ----
李四 74 84 94 84.00 252
张三 74 83 93 83.33 250
*/

--SQL SERVER 2000 静态SQL。
select 姓名 姓名,
max(case 课程 when '语文' then 分数 else 0 end) 语文,
max(case 课程 when '数学' then 分数 else 0 end) 数学,
max(case 课程 when '物理' then 分数 else 0 end) 物理,
cast(avg(分数*1.0) as decimal(18,2)) 平均分,
sum(分数) 总分
from tb
group by 姓名

--SQL SERVER 2000 动态SQL。
declare @sql varchar(8000)
set @sql = 'select 姓名 '
select @sql = @sql + ' , max(case 课程 when ''' + 课程 + ''' then 分数 else 0 end) [' + 课程 + ']'
from (select distinct 课程 from tb) as a
set @sql = @sql + ' , cast(avg(分数*1.0) as decimal(18,2)) 平均分 , sum(分数) 总分 from tb group by 姓名'
exec(@sql)

--SQL SERVER 2005 静态SQL。
select m.* , n.平均分 , n.总分 from
(select * from (select * from tb) a pivot (max(分数) for 课程 in (语文,数学,物理)) b) m,
(select 姓名 , cast(avg(分数*1.0) as decimal(18,2)) 平均分 , sum(分数) 总分 from tb group by 姓名) n
where m.姓名 = n.姓名

--SQL SERVER 2005 动态SQL。
declare @sql varchar(8000)
select @sql = isnull(@sql + ',' , '') + 课程 from tb group by 课程
exec ('select m.* , n.平均分 , n.总分 from
(select * from (select * from tb) a pivot (max(分数) for 课程 in (' + @sql + ')) b) m ,
(select 姓名 , cast(avg(分数*1.0) as decimal(18,2)) 平均分 , sum(分数) 总分 from tb group by 姓名) n
where m.姓名 = n.姓名')

其他实例

http://topic.csdn.net/u/20100708/18/55df5a90-27a7-4452-a69a-27f735539a1f.html?seed=24842417&r=66831902#r_66831902


--3、不同数据按照序号转为列,方法基本同 1

if object_id('tb1') is not null drop table tb1
go
CREATE table tb1 --数据表
(
cpici varchar(10) not null,
cname varchar(10) not null,
cvalue int null
)
--插入测试数据
INSERT INTO tb1 values('T501','x1',31)
INSERT INTO tb1 values('T501','x1',33)
INSERT INTO tb1 values('T501','x1',5)

INSERT INTO tb1 values('T502','x1',3)
INSERT INTO tb1 values('T502','x1',22)
INSERT INTO tb1 values('T502','x1',3)

INSERT INTO tb1 values('T503','x1',53)
INSERT INTO tb1 values('T503','x1',44)
INSERT INTO tb1 values('T503','x1',50)
INSERT INTO tb1 values('T503','x1',23)


--在sqlserver2000里需要用自增辅助
alter table tb1 add id int identity
go
declare @s varchar(8000)
set @s='select cpici '
select @s=@s+',max(case when rn='+ltrim(rn)+' then cvalue end) as cvlue'+ltrim(rn)
from (select distinct rn from (select rn=(select count(1) from tb1 where cpici=t.cpici and id<=t.id) from tb1 t)a)t
set @s=@s+' from (select rn=(select count(1) from tb1 where cpici=t.cpici and id<=t.id),* from tb1 t
) t group by cpici'

exec(@s)
go
alter table tb1 drop column id

--再2005就可以用row_number
declare @s varchar(8000)
set @s='select cpici '
select @s=@s+',max(case when rn='+ltrim(rn)+' then cvalue end) as cvlue'+ltrim(rn)
from (select distinct rn from (select rn=row_number()over(partition by cpici order by getdate()) from tb1)a)t
set @s=@s+' from (select rn=row_number()over(partition by cpici order by getdate()),* from tb1
) t group by cpici'

exec(@s)

---结果
/*
cpici cvlue1 cvlue2 cvlue3 cvlue4
---------- ----------- ----------- ----------- -----------
T501 31 33 5 NULL
T502 3 22 3 NULL
T503 53 44 50 23
警告: 聚合或其他 SET 操作消除了空值。

(3 行受影响)

*/


--测试用
IF OBJECT_ID('[tb]') IS NOT NULL DROP TABLE [tb]
GO
create table tb(电话号码 varchar(15), 通话时长 int ,行业 varchar(10))
insert tb
select '13883633601', 10 ,'餐饮' union all
select '18689704236', 20 ,'物流' union all
select '13883633601', 20 ,'物流' union all
select '13883633601', 20 ,'汽车' union all
select '18689704236', 20 ,'医疗' union all
select '18689704236', 20 ,'it' union all
select '18689704236', 20 ,'汽车' union all
select '13883633601', 50 ,'餐饮'
go

declare @sql varchar(8000)
set @sql='select 电话号码,sum(通话时长) 通话总和'
select @sql=@sql+',max(case when rowid='+ltrim(rowid)+' then 行业 else '''' end) as [行业'+ltrim(rowid)+']'
from (select distinct rowid from (select (select count(distinct 行业) from tb where 电话号码=t.电话号码 and 行业<=t.行业) rowid
from tb t) a) b
set @sql=@sql+' from ( select * , (select count(distinct 行业) from tb where 电话号码=t.电话号码 and 行业<=t.行业) rowid
from tb t ) t group by 电话号码'
exec(@sql)

--结果
/*

(所影响的行数为 8 行)

电话号码 通话总和 行业1 行业2 行业3 行业4
--------------- ----------- ---------- ---------- ---------- ----------
13883633601 100 餐饮 汽车 物流
18689704236 80 it 汽车 物流 医疗

(所影响的行数为 2 行)

*/
bala7229291 2011-03-24
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 fredrickhu 的回复:]
SQL code
select
max(case a when 'a' then a else '' end) as a,
max(case a when 'b' then a else '' end) as b,
max(case a when 'c' then a else '' end) as c,
max(case a when 'd' then a el……
[/Quote]
如果我能取出这一列,可不是这列有多少行,换句话说,a列有多少个值,我就转换成一条记录的多少列
王向飞 2011-03-24
  • 打赏
  • 举报
回复
拷贝-excel-选择性粘贴- 行列转换
--小F-- 2011-03-24
  • 打赏
  • 举报
回复
select
max(case a when 'a' then a else '' end) as a,
max(case a when 'b' then a else '' end) as b,
max(case a when 'c' then a else '' end) as c,
max(case a when 'd' then a else '' end) as d,
max(case a when 'e' then a else '' end) as e,
max(case a when 'f' then a else '' end) as f,
max(case a when 'g' then a else '' end) as g
from
tb
--小F-- 2011-03-24
  • 打赏
  • 举报
回复
select
max(case a when a then a else '' end) as a,
max(case b when a then a else '' end) as b,
max(case c when a then a else '' end) as c,
max(case d when a then a else '' end) as d,
max(case e when a then a else '' end) as e,
max(case f when a then a else '' end) as f,
max(case g when a then a else '' end) as g
from
tb
wjswshujun 2011-03-24
  • 打赏
  • 举报
回复
经典帖子里面多的很

34,593

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧