有这样的三张表,记录表(id,compid 单位编号,happentime 发生时间,protypeid 问题类型),问题类型表(proid,……),单位表(compid单位编号,compname单位名称)。
要做一下三种统计:
一:统计某一时间段内某单位不同问题的汇总情况
选择好具体单位,起始时间、截止时间
生成一下这样的结果: 时间 问题1 问题2 问题3
2002(起始时间) 2 4 6
2003 6 8 1
2004(截止时间) 6 8 9
即统计一个单位在一个时间段内每年对应的问题类型的发生个数。二:统计某一时间段内各单位不同问题的汇总情况
选择好起始时间、截止时间生成这样的统计结果:单位 问题1 问题2 问题3
单位1 2 3 6
单位2 4 5 7即统计不同单位在这段时间内对应的每种问题发生个数三:针对某个问题,统计某一时间段内各年度的汇总情况
选择开始时间、截止时间、问题分类生成以下这样结果:
单位 2002以前 2003 2004
单位1 12 4 23
单位2 29 3 12
即统计每个单位在这个时间段内每年某具体问题的发生情况
原来的做法是通过代码来设计好相应的datatable,然后在这个datatable里添加列,最后手动添加每条记录。这种方法比较死板,而且速度慢,因为每条记录的每个属性的值都是统计出来的。在oracle中有没有方式来实现这样的统计啊?
原先考虑过在oracle中生成临时表来做,原理和写代码设计datatable差不多。
如果在oracle中做,是不是要写些比较复杂的存储过程?
要做一下三种统计:
一:统计某一时间段内某单位不同问题的汇总情况
选择好具体单位,起始时间、截止时间
生成一下这样的结果: 时间 问题1 问题2 问题3
2002(起始时间) 2 4 6
2003 6 8 1
2004(截止时间) 6 8 9
即统计一个单位在一个时间段内每年对应的问题类型的发生个数。二:统计某一时间段内各单位不同问题的汇总情况
选择好起始时间、截止时间生成这样的统计结果:单位 问题1 问题2 问题3
单位1 2 3 6
单位2 4 5 7即统计不同单位在这段时间内对应的每种问题发生个数三:针对某个问题,统计某一时间段内各年度的汇总情况
选择开始时间、截止时间、问题分类生成以下这样结果:
单位 2002以前 2003 2004
单位1 12 4 23
单位2 29 3 12
即统计每个单位在这个时间段内每年某具体问题的发生情况
原来的做法是通过代码来设计好相应的datatable,然后在这个datatable里添加列,最后手动添加每条记录。这种方法比较死板,而且速度慢,因为每条记录的每个属性的值都是统计出来的。在oracle中有没有方式来实现这样的统计啊?
原先考虑过在oracle中生成临时表来做,原理和写代码设计datatable差不多。
如果在oracle中做,是不是要写些比较复杂的存储过程?
解决方案 »
- oracle 中一个字符串放在 varchar2(100)和varchar2(4000)字段中用的空间都是一样的吗?如果一样还用定义长度干什么?
- SQLPLUS连接加了SID无法连接!
- oracle如何将查出来的数据导出?
- 如果有十几二十个参数要传入存储过程处理,有没有什么简洁的方法?
- 有个表a(x number(20),y number(20))用最快速高效的SQL向该表插入从1开始的连续的1000万记录
- 基本问题,谁能帮我解答
- 请教谁有toadXpert的永久注册码?
- 不知如何是好,请各位帮忙看看!
- 怎样复制整个oracle92的数据库结构?
- Oracle菜鸟,请教各位高手,如何在C#里使用Oracle?
- sql 查询 过滤 数值内容
- 请问大家一个通过一张表更新另一张表的问题,大家帮帮忙啊
2, select B.compname,sum(decode(protypeid,'问题1',1)),sum(decode(protypeid,'问题2',1)),sum(decode(protypeid,'问题3',1)) from 记录表 A inner join 单位表 B
on A.compid=B. compid group by B.compname
3, select B.compname,
sum
(case when
A.happentime <2002
then 1
else
0 end ),sum
(case when
A.happentime =2003
then 1
else
0 end ),sum
(case when
A.happentime =2004
then 1
else
0 end ) from 记录表 A inner join 单位表 B
on A.compid=B. compid group by B.compname好久没写SQL了``可能一俩个语法弄错一点 你自己调一下
select to_char(a.happentime,'yyyy'),count(decode(a.protypeid,1,1))问题1,
count(decode(a.protypeid,2,1))问题2,
count(decode(a.protypeid,3,1))问题3
from a
where happentime between .. and ..
group by to_char(a.happentime,'yyyy')
2.
select b.compname,count(decode(a.protypeid,1,1))问题1,
count(decode(a.protypeid,2,1))问题2,
count(decode(a.protypeid,3,1))问题3
from a,b
where a.id=b.compid
and a.happentime between .. and ..
group by b.compname
3.
select b.compname,count(case when a.happentime<date'2002-1-1' then 1 end)"2002以前",
count(case when trunc(a.happentime,'yy')=date'2003-1-1' then 1 end)"2003",
count(case when trunc(a.happentime,'yy')=date'2004-1-1' then 1 end)"2004"
from a,b
where a.id=b.compid
and a.happentime between .. and ..
group by b.compname
问题类型的字段是不确定的!还有就是针对统计一,生成的表的记录按给定的时间段显示的,譬如是从2001年到2003年,则表记录如下:时间 问题1 ,问题2,……
2001 3, 5,……
2002 4, 8,……
2003 2, 1,现在有个问题就是:怎么用select语句得到这样的一个查询结果,查询结果的字段是问题类型表的记录的一个属性值。
那就BETWEEN 2001 AND 2003 GROUP BY YEAR就是了
如果字段是不确定的就动态拼SQL啊
有几个字段 循环里添加上去
这个循环语句怎么写啊?以前遇到这种情况都是自己在程序中写代码生成datatable,太麻烦,速度还慢
FOR i in 1 .. type_field.COUNT LOOP
v_sqlhead := v_sqlhead ||
'to_char((select xmmc from t_xt_hmxmjbxxb where id=' ||
type_field(i) || '))';
v_sqlbody := v_sqlbody || 'to_char(SUM(decode(a.XMID,' ||
type_field(i) || ', a.JE,0)))';
v_sqlbody := v_sqlbody || ' je' || type_field(i);
v_sqlbodyhead := v_sqlbodyhead || 'to_char(sum(t' || type_field(i) || '))';
v_sqlname := v_sqlname || 'nvl(je' || type_field(i) || ',0) t' ||
type_field(i);
IF i < type_field.COUNT THEN
v_sqlhead := v_sqlhead || ',';
v_sqlbody := v_sqlbody || ',';
v_sqlname := v_sqlname || ',';
v_sqlbodyhead := v_sqlbodyhead || ',';
END IF;
v_sqlhead := v_sqlhead || CHR(13) || CHR(10);
v_sqlbody := v_sqlbody || CHR(13) || CHR(10);
v_sqlname := v_sqlname || CHR(13) || CHR(10);
v_sqlbodyhead := v_sqlbodyhead || CHR(13) || CHR(10);
END LOOP;
这是一小段DEMO `不懂的再问我
你有qq或者msn么?刚接触动态sql,很菜
这个是对type_field做循环 你不是查出所有的动态列了吗
做循环 然后一个一个的加上去 拼SQL
研究了这么一个过程(只是针对问题一,二三应该类似),楼主看看有没有用create or replace
PROCEDURE ABOUT_RECORD
( begindate IN char , enddate IN char , compid_in IN number , asql out VARCHAR2, cur out sys_refcursor )
AS
sql1 VARCHAR2(1000);
sql2 varchar2(1000);
cursor cur_t
is
select distinct protypeid from record where compid= compid_in order by protypeid;
BEGIN
FOR aRecord in cur_t
LOOP
sql1:= sql1 || ',sum(pt' || aRecord.protypeid || ') as 问题_' || aRecord.protypeid;
sql2:= sql2 || ',case when protypeid=' || aRecord.protypeid || ' then 1 else 0 end as pt' || aRecord.protypeid;
END LOOP;
Asql:='select to_char(happentime,''yyyy'') as year' || sql1 ||
' from (select compid,happentime' || sql2 ||
' from record) a where compid=' || compid_in ||
' and happentime between to_date(''' || begindate || ''',''yyyymmdd'') and to_date(''' ||
enddate || ''',''yyyymmdd'') group by to_char(happentime, ''yyyy'')';
open cur for asql;
END ABOUT_RECORD;在sqlplus中可以以下这样调用
variable bd char(10);
variable cur refcursor;
variable ed char(10);
variable cid_in number;
var asql varchar2(2000);
begin
:bd :='20070101';
:ed :='20100101';
:cid_in:=1;
end ;
/
EXECUTE about_record(:bd,:ed,:cid_in,:asql,:cur);
print :cur;
print :asql;其中bd是起始日期,ed是终止日期,cin_in是单位id,asql就是动态拼成的sql语句
用了你的方法,但是cur如何关闭啊?
打印了一次就不能再次打印了,还有,c#该怎么获取游标的值呢?并转成dataset啊?