比竖表转横表还难的问题。

zsl6658 2009-03-05 09:18:46
记录时间 次数
2009-3-4 00:01:10 3
2009-3-4 01:01:10 4
2009-3-4 02:01:10 5
2009-3-4 03:01:10 6
.................................
2009-3-4 23:01:10 26
2009-3-5 00:01:10 21
2009-3-5 01:01:10 22
..................................
2009-3-5 23:01:10 224
...................................
2009-3-6 00:01:10 225
2009-3-6 01:01:10 226
....................................
2009-3-6 23:01:10 227
...................................

怎么把这样的表转为
小时 4日次数 5日次数 6日次数 ..........
0 3 21 225
1 4 22 226
..............................................
23 26 224 227


转前表的数据是记录每天每小时在线人数。

转之后需要统计当前日期前7天每小时在线人数。

请问大侠们这个问题怎么搞定?

最好sqlserver和oracle都有解。
...全文
148 4 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
cqhy123 2009-05-14
  • 打赏
  • 举报
回复
http://blog.csdn.net/chenxiaohua/archive/2008/01/08/2030884.aspx

关于竖表转横表的问题收藏
在实际的应用中,我们经常遇到需要转换数据显示方式,比如将横表转为竖表,或将竖表转换为横表的情况,如:课程表的显示方式,部门平均工资的排名等情况。下面将将根据两个实例子的需求描述给出两种常见的竖表转横表的解决办法(本例中的数据意思是:一、二、三年级的各科目最高分统计)。
表结构:
create table test_table
(
grade_id number(8), --年级:1、一年级,2、二年级,3、三年级
subject_name varchar2(30), --科目:包含语文、数学、外语、政治等科目
max_score number(8) --最高分
)


表中数据:
SQL> select * from test_table;
GRADE_ID SUBJECT_NAME MAX_SCORE
1 语文 95
1 数学 98
2 语文 86
2 数学 90
2 政治 87
3 语文 93
3 数学 88
3 英语 88
3 政治 97
9 rows selected.

第一种转换方式:
需求描述:查看每个年级在系统中存在的科目信息,并各年级的科目信息按下面的格式显示:
GRADE_ID SUBJECT_NAME
1 语文 数学
    2 语文 数学 政治
     3 语文 数学 英语 政治
分析:在要求得到的结果中,每个年级的科目将变成一条记录,而且每个年级的科目是不固定的。所以考虑写个函数来解决,输入年级信息,使用游标得到该年级的所有科目信息并返回值。
1、建函数:
SQL> create or replace function test_fun(p_grade number) return varchar2 as
2 v_temp varchar2(100):='';
3 v_out varchar2(500):='';
4 cursor c is select a.subject_name from test_table a where a.grade_id=p_grade;
5 begin
6 open c ;   --打开游标
7 loop
8 fetch c into v_temp;
9 exit when c%notfound;
10 v_out:=v_out||' '||v_temp;
11 end loop;
12 close c; --关闭游标
13 return v_out;
14 exception
15 when others then
16 return 'An error occured';
17 end ;
18 /
Function created.

SQL> create or replace function test_fun(p_grade number) return varchar2 as
2 v_out varchar2(500):='';
3 cursor c is select a.subject_name from test_table a where a.grade_id=p_grade;
4 begin
5 for v_temp in c loop
6 v_out:=v_out||' '||v_temp.subject_name;
7 end loop; --系统自动关闭游标
8 return v_out;
9 exception
10 when others then
11 return 'An error occured';
12 end ;
13 /
Function created.

2、调用函数得到输入结果:
SQL> select distinct a.grade_id,test_fun(a.grade_id) subject from test_table a;
GRADE_ID SUBJECT
1 语文 数学
2 语文 数学 政治
3 语文 数学 英语 政治

第二种转换方式:
需求描述:要求将表中的年级、科目及最高的信息按照下表的格式显示,如果该年级没开的课程,则其最高分用0表示:
年级 语文 数学 英语      政治
一年级 95 98 0 0
二年级 86 90 0 87
三年级 93 88 88 97

分析:该需求将年级的分数及科目信息由纵向转为横向,这样就要针对每个年级的,对其科目进行判断,存在科目则显示科目的最高分,如果不存在显示0。这时候就考虑到使用decode函数来解决。实现如下:
select
decode(t.grade_id,1,'一年级',2,'二年级',3,'三年级') 年级,
sum(decode(t.subject_name,’语文’,t.max_score,0)) 语文,
sum(decode(t.subject_name,'数学',t.max_score,0)) 数学,
sum(decode(t.subject_name,'英语',t.max_score,0)) 英语,
sum(decode(t.subject_name,'政治',t.max_score,0)) 政治
sum(max_score) 总分
from
test_table t
group by
t.grade_id

需要说明的是,在第一种转换方式中写了两个函数,两个函数实现的是同一个需求,所不同的是,两个函数中游标使用方式不同,地一个函数中手动打开游标,循环结束后要求手动关闭。而后一个函数使用for 循环,循环结束后系统自动关闭光标。在第二种转换方式中,使用了decode函数,关于decode的详细用法,请参考oracle函数相关文档。
总  结:
上面的两种转换方式是在开发中经常遇到的情况,在开发中的其他类似的转换都可以参考上面的转换方式,使用decode,nvl等函数进行一些特别的处理即可得到想要的显示方式.
zai_xv 2009-03-15
  • 打赏
  • 举报
回复
帮顶
msword2007 2009-03-06
  • 打赏
  • 举报
回复
帮顶
zsl6658 2009-03-05
  • 打赏
  • 举报
回复
自己顶一个,每人能搞定这个问题?

6,108

社区成员

发帖
与我相关
我的任务
社区描述
其他数据库开发 数据库报表
社区管理员
  • 数据库报表社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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