急:求助纵表转横表

wangzgwf 2009-02-09 04:46:36
急:哪位大哥帮我一下,我想把下列格式(表中主叫最多有10个)
主叫 被叫 拨打次数
a b 10
a c 9
a d 7
b e 20
b f 18
转化为以下形式的格式()

a b/10 c/9 d/7
b e/20 f/18
...全文
464 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
Andy__Huang 2009-02-10
  • 打赏
  • 举报
回复
一样的道理;
select col1,wmsys.wm_concat(col2,',',' ') col2
from tb
group by col1;
这个语句 oracle10g 可以,但10g之前的版本不行
wangzgwf 2009-02-10
  • 打赏
  • 举报
回复
再说明一下,第一列一样但第二列不一样的记录最多为10条
wangzgwf 2009-02-10
  • 打赏
  • 举报
回复
我可能没有说清楚,我的第一列和第二列是不确定的,第三列表示以第一列和第二列分组后所得的数量,我现在要把第一列一样但第二列不一样的放到一个横表里
Andy__Huang 2009-02-09
  • 打赏
  • 举报
回复

SQL> select col1,replace(wmsys.wm_concat(aa),',',' ') aa
2 from (select col1,col2||'/'||to_char(col3) aa from ta)
3 group by col1;

结果:
col1 aa
- -------------------
a b/10 c/9 d/7
b e/20 f/18

这是在oracle 10g下面运行
Andy__Huang 2009-02-09
  • 打赏
  • 举报
回复
dawugui 来回就看到用这个例子来回帖,能够解决数主的问题吗?
dawugui 2009-02-09
  • 打赏
  • 举报
回复
[Quote=引用楼主 wangzgwf 的帖子:]
急:哪位大哥帮我一下,我想把下列格式(表中主叫最多有10个)
主叫 被叫 拨打次数
a b 10
a c 9
a d 7
b e 20
b f 18
转化为以下形式的格式()

a b/10 c/9 d/7
b e/20 f/18
[/Quote]
如果你的被叫不是固定的,先通过主叫+被叫生成一个序列数,然后对这个序列数进行行列转换.

select 主叫,
max(case px when 1 then 被叫 || '/' || to_char(拨打次数) else '' end) col1,
max(case px when 2 then 被叫 || '/' || to_char(拨打次数) else '' end) col2,
...
max(case px when n then 被叫 || '/' || to_char(拨打次数) else '' end) coln
from (select t.* , row_number() over(partition by 主叫 order by 被叫) px from tb t) m
group by 主叫
dawugui 2009-02-09
  • 打赏
  • 举报
回复
--如果数量不定,oracle动态不会,请参考我SQL SERVER的动态转换.


/*
标题:普通行列转换(version 2.0)
作者:爱新觉罗.毓华(十八年风雨,守得冰山雪莲花开)
时间:2008-03-09
地点:广东深圳
说明:普通行列转换(version 1.0)仅针对sql server 2000提供静态和动态写法,version 2.0增加sql server 2005的有关写法。

问题:假设有张学生成绩表(tb)如下:
姓名 课程 分数
张三 语文 74
张三 数学 83
张三 物理 93
李四 语文 74
李四 数学 84
李四 物理 94
想变成(得到如下结果):
姓名 语文 数学 物理
---- ---- ---- ----
李四 74 84 94
张三 74 83 93
-------------------
*/

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,指课程只有语文、数学、物理这三门课程。(以下同)
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 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 SERVER 2005 静态SQL。
select * from (select * from tb) a pivot (max(分数) for 课程 in (语文,数学,物理)) b

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

---------------------------------

/*
问题:在上述结果的基础上加平均分,总分,得到如下结果:
姓名 语文 数学 物理 平均分 总分
---- ---- ---- ---- ------ ----
李四 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.姓名')

drop table tb

------------------
------------------

/*
问题:如果上述两表互相换一下:即表结构和数据为:
姓名 语文 数学 物理
张三 74  83  93
李四 74  84  94
想变成(得到如下结果):
姓名 课程 分数
---- ---- ----
李四 语文 74
李四 数学 84
李四 物理 94
张三 语文 74
张三 数学 83
张三 物理 93
--------------
*/

create table tb(姓名 varchar(10) , 语文 int , 数学 int , 物理 int)
insert into tb values('张三',74,83,93)
insert into tb values('李四',74,84,94)
go

--SQL SERVER 2000 静态SQL。
select * from
(
select 姓名 , 课程 = '语文' , 分数 = 语文 from tb
union all
select 姓名 , 课程 = '数学' , 分数 = 数学 from tb
union all
select 姓名 , 课程 = '物理' , 分数 = 物理 from tb
) t
order by 姓名 , case 课程 when '语文' then 1 when '数学' then 2 when '物理' then 3 end

--SQL SERVER 2000 动态SQL。
--调用系统表动态生态。
declare @sql varchar(8000)
select @sql = isnull(@sql + ' union all ' , '' ) + ' select 姓名 , [课程] = ' + quotename(Name , '''') + ' , [分数] = ' + quotename(Name) + ' from tb'
from syscolumns
where name! = N'姓名' and ID = object_id('tb') --表名tb,不包含列名为姓名的其它列
order by colid asc
exec(@sql + ' order by 姓名 ')

--SQL SERVER 2005 动态SQL。
select 姓名 , 课程 , 分数 from tb unpivot (分数 for 课程 in([语文] , [数学] , [物理])) t

--SQL SERVER 2005 动态SQL,同SQL SERVER 2000 动态SQL。

--------------------
/*
问题:在上述的结果上加个平均分,总分,得到如下结果:
姓名 课程 分数
---- ------ ------
李四 语文 74.00
李四 数学 84.00
李四 物理 94.00
李四 平均分 84.00
李四 总分 252.00
张三 语文 74.00
张三 数学 83.00
张三 物理 93.00
张三 平均分 83.33
张三 总分 250.00
------------------
*/

select * from
(
select 姓名 as 姓名 , 课程 = '语文' , 分数 = 语文 from tb
union all
select 姓名 as 姓名 , 课程 = '数学' , 分数 = 数学 from tb
union all
select 姓名 as 姓名 , 课程 = '物理' , 分数 = 物理 from tb
union all
select 姓名 as 姓名 , 课程 = '平均分' , 分数 = cast((语文 + 数学 + 物理)*1.0/3 as decimal(18,2)) from tb
union all
select 姓名 as 姓名 , 课程 = '总分' , 分数 = 语文 + 数学 + 物理 from tb
) t
order by 姓名 , case 课程 when '语文' then 1 when '数学' then 2 when '物理' then 3 when '平均分' then 4 when '总分' then 5 end

drop table tb
dawugui 2009-02-09
  • 打赏
  • 举报
回复
参考:

/*
标题:静态行列转换
作者:爱新觉罗.毓华
时间:2008-05-05
地点:广东深圳
*/

/*
col1 col2 col3
A x 1
A y 2
A z 3
B x 2
B y 1
B z 1

转换为

col1 x y z
A 1 2 3
B 2 1 1
*/

create table tb(col1 varchar2(10) , col2 varchar2(10) , col3 varchar2(10))
insert into tb values('A' , 'x' , '1')
insert into tb values('A' , 'y' , '2')
insert into tb values('A' , 'z' , '3')
insert into tb values('B' , 'x' , '2')
insert into tb values('B' , 'y' , '1')
insert into tb values('B' , 'z' , '1')

--1
select col1,
max(case col2 when 'x' then col3 else '' end) x,
max(case col2 when 'y' then col3 else '' end) y,
max(case col2 when 'z' then col3 else '' end) z
from tb
group by col1

--2
select col1 ,
max(decode(col2 , 'x' , col3)) x,
max(decode(col2 , 'y' , col3)) y,
max(decode(col2 , 'z' , col3)) z
from tb
group by col1

drop table tb

/*
COL1 X Y Z
---------- ---------- ---------- ----------
A 1 2 3
B 2 1 1
2 rows selected
*/

风险点 作业步骤/检查项目 危险源或潜在事件 评价级别 管控级别 主要后果 管控措施 管控层级 责任单位 责任人 备注 序号 类型 名称 设备设施/作业活动 序号 名称 工程技术 管理措施 培训教育 个体防护 应处理 1 其他设备 数控开卷纵剪生产线 3级 机械伤害、物体打击 车间 生产部 1、建立安全管理制度规章;2、岗位点检、定期巡检和周期性更换。 1、按公司、车间年度培训计划对员工进行三级安全教育,其中年度公司级安全再培训不低于8学时(初次培训时间不得少于24学时);2、按计划定期进行每次不低于1小时的事故警示教育;3、按计划进行事故应培训和演练。 规范穿着工作服、安全帽、戴防护眼镜、防护手套 1、立即停止运行或按停;2、无关人员撤至安全区;3、断电、挂牌、安排专人监护;4、发生机械伤害、触电、高处坠落、物体打击事故,立即启动各类事故应预案,并拨打120进行报警求助。发生火灾爆炸后,关闭设备单机电源。使用就近灭火器及消防栓进行灭火,通过电话向公司值班人员报警,火灾进一步扩大时应及时拨打119报警,正确引导所有员工沿着最近的安全出口疏散。 2 其他设备 数控开卷纵剪生产线 3级 机械伤害、物体打击 车间 生产部 1、建立安全管理制度规章;2、岗位点检、定期巡检和周期性更换。 1、按公司、车间年度培训计划对员工进行三级安全教育,其中年度公司级安全再培训不低于8学时(初次培训时间不得少于24学时);2、按计划定期进行每次不低于1小时的事故警示教育;3、按计划进行事故应培训和演练。 规范穿着工作服、安全帽、戴防护眼镜、防护手套 1、立即停止运行或按停;2、无关人员撤至安全区;3、断电、挂牌、安排专人监护;4、发生机械伤害、触电、高处坠落、物体打击事故,立即启动各类事故应预案,并拨打120进行报警求助。发生火灾爆炸后,关闭设备单机电源。使用就近灭火器及消防栓进行灭火,通过电话向公司值班人员报警,火灾进一步扩大时应及时拨打119报警,正确引导所有员工沿着最近的安全出口疏散。 3 其他设备 数控开卷矫平横剪线 3级 机械伤害、物体打击 车间 生产部 1、建立安全管理制度规章;2、岗位点检、定期巡检和周期性更换。 1、按公司、车间年度培训计划对员工进行三级安全教育,其中年度公司级安全再培训不低于8学时(初次培训时间不得少于24学时);2、按计划定期进行每次不低于1小时的事故警示教育;3、按计划进行事故应培训和演练。 规范穿着工作服、安全帽、戴防护眼镜、防护手套。 1、立即停止运行或按停;2、无关人员撤至安全区;3、断电、挂牌、安排专人监护;4、发生机械伤害、触电、高处坠落、物体打击事故,立即启动各类事故应预案,并拨打120进行报警求助。发生火灾爆炸后,关闭设备单机电源。使用就近灭火器及消防栓进行灭火,通过电话向公司值班人员报警,火灾进一步扩大时应及时拨打119报警,正确引导所有员工沿着最近的安全出口疏散 4 其他设备 数控开卷矫平横剪线 3级 机械伤害、物体打击 车间 生产部 1、建立安全管理制度规章;2、岗位点检、定期巡检和周期性更换。 1、按公司、车间年度培训计划对员工进行三级安全教育,其中年度公司级安全再培训不低于8学时(初次培训时间不得少于24学时);2、按计划定期进行每次不低于1小时的事故警示教育;3、按计划进行事故应培训和演练。 规范穿着工作服、安全帽、戴防护眼镜、防护手套。 1、立即停止运行或按停;2、无关人员撤至安全区;3、断电、挂牌、安排专人监护;4、发生机械伤害、触电、高处坠落、物体打击事故,立即启动各类事故应预案,并拨打120进行报警求助。发生火灾爆炸后,关闭设备单机电源。使用就近灭火器及消防栓进行灭火,通过电话向公司值班人员报警,火灾进一步扩大时应及时拨打119报警,正确引导所有员工沿着最近的安全出口疏散 5 其他设备 数控开卷矫平飞剪生产线 3级 机械伤害、物体打击 车间 生产部 1、建立安全管理制度规章;2、岗位点检、定期巡检和周期性更换。 规范穿着工作服、安全帽、戴防护眼镜、防护手套。 1、立即停止运行或按停;2、无关人员撤至安全区;3、断电、挂牌、安排专人监护;4、发生中毒窒息、机械伤害、触电、高处坠落、物体打击事故,立即启动各类事故应预案,并拨打120进行报警求助。 6 其他设备 数控开卷矫平纵剪生产线 3级 机械伤害、物体打击 车间 生产部 1、建立安全管理制度规章;2、岗位点检、定期巡检和周期性更换。 规范穿着工作服、安全帽、戴防护眼镜、防护手套。 1、立即停止运行或按停;2、无关人员撤至安全区;3、

3,491

社区成员

发帖
与我相关
我的任务
社区描述
Oracle 高级技术相关讨论专区
社区管理员
  • 高级技术社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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