建表语句如下:
create table tb(dtime varchar2(30), accountname varchar2(10));insert into tb(dtime, accountname) values('20110513','A');
insert into tb(dtime, accountname) values('20110513','B');
insert into tb(dtime, accountname) values('20110513','C');
insert into tb(dtime, accountname) values('20110513','D');
insert into tb(dtime, accountname) values('20110514','A');
insert into tb(dtime, accountname) values('20110514','B');
insert into tb(dtime, accountname) values('20110514','C');
insert into tb(dtime, accountname) values('20110514','E');insert into tb(dtime, accountname) values('20110515','A');
insert into tb(dtime, accountname) values('20110515','B');
insert into tb(dtime, accountname) values('20110515','E');
insert into tb(dtime, accountname) values('20110515','F');insert into tb(dtime, accountname) values('20110516','A');
insert into tb(dtime, accountname) values('20110516','E');
insert into tb(dtime, accountname) values('20110516','I');
insert into tb(dtime, accountname) values('20110516','J');
commit;
dtime: 登录时间 accountname:登录用户根据输入的开始和结束时间,要求开始时间显示新增用户总数,其余时间显示新增用户连续登录的总数
例如:
场景1:
输入:20110513-20110514
输出:20110513 20110514
4 3
说明:20110513新增了4个用户ABCD,故为4; 20110514登录了ABC,故为3;场景2:
输入:20110513-20110515
输出:20110513 20110514 20110515
4 3 2
说明:20110513新增了4个用户ABCD,故为4; 20110514登录了ABC,故为3;20110515登录了AB,故为2;场景3:
输入:20110513-20110516
输出:20110513 20110514 20110515 20110516
4 3 2 1
说明:20110513新增了4个用户ABCD,故为4; 20110514登录了ABC,故为3;20110515登录了AB,故为2;20110516登录了A,故为1
场景4:
输入:20110514-20110515
输出:20110513 20110514
1 1
说明:20110514新增了用户E,故为1;20110515 登录了E,故为1
create table tb(dtime varchar2(30), accountname varchar2(10));insert into tb(dtime, accountname) values('20110513','A');
insert into tb(dtime, accountname) values('20110513','B');
insert into tb(dtime, accountname) values('20110513','C');
insert into tb(dtime, accountname) values('20110513','D');
insert into tb(dtime, accountname) values('20110514','A');
insert into tb(dtime, accountname) values('20110514','B');
insert into tb(dtime, accountname) values('20110514','C');
insert into tb(dtime, accountname) values('20110514','E');insert into tb(dtime, accountname) values('20110515','A');
insert into tb(dtime, accountname) values('20110515','B');
insert into tb(dtime, accountname) values('20110515','E');
insert into tb(dtime, accountname) values('20110515','F');insert into tb(dtime, accountname) values('20110516','A');
insert into tb(dtime, accountname) values('20110516','E');
insert into tb(dtime, accountname) values('20110516','I');
insert into tb(dtime, accountname) values('20110516','J');
commit;
dtime: 登录时间 accountname:登录用户根据输入的开始和结束时间,要求开始时间显示新增用户总数,其余时间显示新增用户连续登录的总数
例如:
场景1:
输入:20110513-20110514
输出:20110513 20110514
4 3
说明:20110513新增了4个用户ABCD,故为4; 20110514登录了ABC,故为3;场景2:
输入:20110513-20110515
输出:20110513 20110514 20110515
4 3 2
说明:20110513新增了4个用户ABCD,故为4; 20110514登录了ABC,故为3;20110515登录了AB,故为2;场景3:
输入:20110513-20110516
输出:20110513 20110514 20110515 20110516
4 3 2 1
说明:20110513新增了4个用户ABCD,故为4; 20110514登录了ABC,故为3;20110515登录了AB,故为2;20110516登录了A,故为1
场景4:
输入:20110514-20110515
输出:20110513 20110514
1 1
说明:20110514新增了用户E,故为1;20110515 登录了E,故为1
解决方案 »
- win7 安装oracle11g成功后,创建数据库实例时出错。数据库服务未注册到监听程序
- 问个有深度的问题哈,关于Timestamp做主键的表,该表下面挂的有触发器,触发到另外的表时,精度变掉了
- exp/imp问题
- 求10个oracle最常用的函数及用法举例
- 关于sql 8.0 plaus的使用
- 菜题:下载的Oracle有什么限制?
- SQL查询速度优化
- 用隐式游标返回一个高级查询,老报错!请高手指点...................
- 今天在Intel C366上装上了Oracle817R3,爽啊!
- 请问怎样用update修改数据?
- oracle 统计排序的问题
- oracle同时查询出表中部分数据和全部数据的问题
要求:根据输入的开始和结束时间,要求开始时间显示新增用户总数,其余时间显示新增用户连续登录的总数。
例如:
场景1:
输入:20110513-20110514
输出:20110513 20110514
4 3
说明:20110513新增了4个用户ABCD,故为4; 20110514登录了ABC,故为3;场景2:
输入:20110513-20110515
输出:20110513 20110514 20110515
4 3 2
说明:20110513新增了4个用户ABCD,故为4; 20110514登录了ABC,故为3;20110515登录了AB,故为2;场景3:
输入:20110513-20110516
输出:20110513 20110514 20110515 20110516
4 3 2 1
说明:20110513新增了4个用户ABCD,故为4; 20110514登录了ABC,故为3;20110515登录了AB,故为2;20110516登录了A,故为1
场景4:
输入:20110514-20110515
输出:20110513 20110514
1 1
说明:20110514新增了用户E,故为1;20110515 登录了E,故为1
--尝试了下,用最基本本的来做的,
--过程如下:
CREATE OR REPLACE procedure p_accoutname(stime varchar2,etime varchar2,cur out sys_refcursor )
is
sql_create varchar2(3000):='create table tmp( ';
sql_insert varchar2(3000):='insert into tmp values(';
cnt number;
cnt2 number:=1;
begin
select count(1) into cnt from user_tables where table_name=upper('tmp') ;
if cnt !=0 then
execute immediate 'drop table tmp';
end if;
for i in stime..etime loop sql_create:=sql_create||'"'||i||'" varchar2(30),';
if cnt2=1 then
select count(1) into cnt from tb a where dtime=i and
not exists(select 1 from tb b where a.accountname=b.accountname and b.dtime<a.dtime) ;
cnt2:=0;
else
select count(1) into cnt from tb c ,
(select a.* from tb a where dtime=stime and not exists
(select 1 from tb b where a.accountname=b.accountname and b.dtime<a.dtime)
) d
where c.accountname=d.accountname and c.dtime=i ;
end if;
sql_insert:=sql_insert||cnt||',';
end loop;
sql_create:=rtrim(sql_create,',') ;
sql_insert:=rtrim(sql_insert,',') ;
sql_create:=sql_create||')';
sql_insert:=sql_insert||')';
--dbms_output.put_line(sql_create);
--dbms_output.put_line(sql_insert);
execute immediate sql_create;
execute immediate sql_insert;
open cur for 'select * from tmp' ;end;
/
--测试:SQL*Plus: Release 8.0.6.0.0 - Production on 星期二 5月 17 16:25:32 2011(c) Copyright 1999 Oracle Corporation. All rights reserved.
Connected to:
Oracle Database 10g Release 10.1.0.2.0 - ProductionSQL> set serveroutput on
SQL> set linesize 32767
SQL> col "20110513" format a10
SQL> col "20110514" format a10
SQL> col "20110515" format a10
SQL> col "20110516" format a10
SQL> var cur refcursor
SQL> exec p_accoutname('20110513','20110514',:cur);PL/SQL procedure successfully completed.SQL> print cur20110513 20110514
---------- ----------
4 3SQL> exec p_accoutname('20110513','20110515',:cur);PL/SQL procedure successfully completed.SQL> print cur20110513 20110514 20110515
---------- ---------- ----------
4 3 2SQL> exec p_accoutname('20110513','20110516',:cur);PL/SQL procedure successfully completed.SQL> print cur20110513 20110514 20110515 20110516
---------- ---------- ---------- ----------
4 3 2 1SQL> exec p_accoutname('20110514','20110515',:cur);PL/SQL procedure successfully completed.SQL> print cur20110514 20110515
---------- ----------
1 1SQL> exec p_accoutname('20110514','20110516',:cur);PL/SQL procedure successfully completed.SQL> print cur20110514 20110515 20110516
---------- ---------- ----------
1 1 1SQL>
--确实杨哥说的是,当初是因为我有个地方卡住了,所以换成procedure了,现在解决了:with tab as(
select '20110514' stime,'20110517' etime from dual
)
select dt,
case when lv =1 then
(select count(1) from tb a where dtime=dt and
not exists(select 1 from tb b where a.accountname=b.accountname and b.dtime<a.dtime)
)
else --就是这里不知道怎么把最外层的stime值传进到最内侧,所以才想用procedure来做。
(select count(1) from tb c ,
(select a.* from tb a,tab where dtime=stime --这里参数stime在最外侧,因此不能传到这里来,这个问题解决了
and not exists (select 1 from tb b where a.accountname=b.accountname and b.dtime<a.dtime)
) d
where c.accountname=d.accountname and c.dtime=dt
)
end as cnt
from (
select stime,stime+level-1 dt,level lv
from tab
connect by level<=etime-stime+1
)
确实复杂,看sql就头晕!
又是内联视图,又是case分支,又是connect by的.........