求一统计计算方法

tanqth 2005-09-12 11:39:30
有一表,内容主要有客户消费情况,如:

客户名,消费起始日期,消费终止日期,消费总金额,日均消费额
A , 2005-09-02 , 2005-09-11, 90 , 10
B , 2005-09-05 , 2005-09-10, 100 , 20
C , 2005-09-11 , 2005-09-18, 140 , 20
D , 2005-09-08 , 2005-09-13, 200 , 40
.......

最后要计算出
日期 收入
2005-09-02 10=(A)
2005-09-03 10=(A)
2005-09-04 10=(A)
2005-09-05 30=(A+B)
2005-09-06 30=(A+B)
2005-09-07 30=(A+B)
2005-09-08 70=(A+B+D)
2005-09-09 70=(A+B+D)
2005-09-10 .......
......

在数据量较大的情况下,用什么样的方法进行计算比较科学有较.




...全文
345 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
Alkeen 2005-09-15
  • 打赏
  • 举报
回复
刚有了数据库,测过,好像没问题
如果要严谨一点,可以在里面的子查询加个where 限制日期 小于 end_date
Alkeen 2005-09-15
  • 打赏
  • 举报
回复
说明:
T-----------------------------楼主的主表名
money-------------------------T表中的日均消费额
start_date,end_date----------分别对应T表中的开始日 和 结束日

上面四个替换跑一下试试?我现在还没环境搞。
user_tables 无所谓,不够就换成足够多记录的表。

Alkeen 2005-09-15
  • 打赏
  • 举报
回复
SELECT the_date,SUM(money)
FROM T,
(SELECT ROWNUM + (SELECT MIN(start_date) FROM T) - 1 AS the_date
FROM user_tables
) S
WHERE the_date >= start_date
AND the_date <= end_date
GROUP BY the_date

这样子可以吧。
loveidea 2005-09-15
  • 打赏
  • 举报
回复
yearlist(泥巴) :
我把你的脚本分析了一下,但是我看不懂t_bi_area,这是个什么表啊,还是试图啊,请您给给说明一下,本人正在学习中,谢谢!能把你的思路说一下吗?
fireflyjava 2005-09-14
  • 打赏
  • 举报
回复
-- Create table
create table CUSTOMER
(
ID VARCHAR2(10),
START_TIME DATE,
END_TIME DATE,
TOTAL_MONEY FLOAT,
AVG_MONEY FLOAT
)

-- Create table
create table STAT
(
DAY DATE,
INCOME FLOAT
)
insert into CUSTOMER (ID, START_TIME, END_TIME, TOTAL_MONEY, AVG_MONEY)
values ('A', to_date('02-09-2005', 'dd-mm-yyyy'), to_date('11-09-2005', 'dd-mm-yyyy'), 90, 10);
insert into CUSTOMER (ID, START_TIME, END_TIME, TOTAL_MONEY, AVG_MONEY)
values ('B', to_date('05-09-2005', 'dd-mm-yyyy'), to_date('10-09-2005', 'dd-mm-yyyy'), 100, 20);
insert into CUSTOMER (ID, START_TIME, END_TIME, TOTAL_MONEY, AVG_MONEY)
values ('C', to_date('11-09-2005', 'dd-mm-yyyy'), to_date('18-09-2005', 'dd-mm-yyyy'), 140, 20);
insert into CUSTOMER (ID, START_TIME, END_TIME, TOTAL_MONEY, AVG_MONEY)
values ('D', to_date('08-09-2005', 'dd-mm-yyyy'), to_date('13-09-2005', 'dd-mm-yyyy'), 200, 40);
commit;

我用存储过程写了一个,如果要定期进行统计的话,就加一个Job
create or replace procedure pro_income
as
minStartTime date;
maxEndTime date;
type customer_cursor is ref cursor;
c_cursor customer_cursor;
c_sql char(150);
type rec_customer is record (start_time date,
end_time date,
vag_money float);
customer rec_customer;
income stat.income%type;

begin
select min(start_time) into minStartTime from customer;
select max(end_time) into maxEndTime from customer;
c_sql:='select c.start_time,c.end_time,avg_money from customer c';
for i in 1..(maxEndTime-minStartTime) loop
open c_cursor for c_sql;
fetch c_cursor into customer;
income:=0;
while c_cursor%found loop
if minStartTime<customer.end_time and minStartTime>=customer.start_time then
income:=income+customer.vag_money;
end if;
fetch c_cursor into customer;
end loop;
close c_cursor;
insert into stat values(minStartTime,income);
commit;
minStartTime:=minStartTime+1;
end loop;
end pro_income;


DAY INCOME
----------- --------------------------------------------------------------------------------
2005-9-2 10
2005-9-3 10
2005-9-4 10
2005-9-5 30
2005-9-6 30
2005-9-7 30
2005-9-8 70
2005-9-9 70
2005-9-10 50
2005-9-11 60
2005-9-12 60
2005-9-13 20
2005-9-14 20
2005-9-15 20
2005-9-16 20
2005-9-17 20
feng2 2005-09-13
  • 打赏
  • 举报
回复
SQL> select * from b;

客户名 消费起始日期 消费终止日期 消费金额 日均消费额
---------- ------------ ------------ ---------- ----------
A 2005-9-2 2005-9-11 90 10
B 2005-9-5 2005-9-10 100 20
C 2005-9-11 2005-9-18 140 20
D 2005-9-8 2005-9-13 200 40

Executed in 0.015 seconds

SQL> select i "日期",(select sum((case when b4 <= i and i <=b5 then b3 else 0 end )) from b) as "收入"
from
(select d+r-1 i,d,m from
(select min(b4) d,max(b5) m from b),
(select rownum r from test where rownum <= (select max(b5)-min(b4)+1 from b))
) k
left join b on k.i=b4
order by i

日期 收入
----------- ----------
2005-9-2 10
2005-9-3 10
2005-9-4 10
2005-9-5 30
2005-9-6 30
2005-9-7 30
2005-9-8 70
2005-9-9 70
2005-9-10 70
2005-9-11 70
2005-9-12 60
2005-9-13 60
2005-9-14 20
2005-9-15 20
2005-9-16 20
2005-9-17 20
2005-9-18 20

17 rows selected

Executed in 0.046 seconds

SQL>



字符串连接的部分,duanzilin有一份详细的说明帖子。
hevin 2005-09-13
  • 打赏
  • 举报
回复
一句SQL应该搞不定的吧。
zealot_zk 2005-09-13
  • 打赏
  • 举报
回复
这个问题好像要使用存储过程来完成,或者使用程序包完成,建议你自己想想,不是很难的,呵呵
yearlist 2005-09-13
  • 打赏
  • 举报
回复
看起来难度较大,先顶一下。
超叔csdn 2005-09-13
  • 打赏
  • 举报
回复
不错不错,学习中!
小李木耳 2005-09-13
  • 打赏
  • 举报
回复
feng2(蜀山风云) 的不管对错,也是刮起风云了。
楼主,不要给我分啊。我只是表白一下。
这种sql要我做没有2个小时都不一定有思路的,学习呀!
yearlist 2005-09-13
  • 打赏
  • 举报
回复
验证了一下,feng2(蜀山风云)的SQL果然没错。高人:)
drop table t_test;

create table t_test(
customer_name varchar(50) null,
sdate date null,
edate date null,
amount number(14,2) null,
avg_amount number(14,2) null
) ;

insert into t_test values ('A','09/02/2005','09/11/2005',90,10);
insert into t_test values ('B','09/05/2005','09/10/2005',90,10);
insert into t_test values ('C','09/11/2005','09/18/2005',140,20);
insert into t_test values ('D','09/08/2005','09/13/2005',200,40);

select i "日期",(select sum((case when sdate <= i and i <=edate then avg_amount else 0 end )) from t_test) as "收入"
from
(select d+r-1 i,d,m from
(select min(sdate) d,max(edate) m from t_test),
(select rownum r from t_bi_area where rownum <= (select max(edate)-min(sdate)+1 from t_test))
) k
left join t_test on k.i=sdate
order by i

日期 金额
09/02/2005 00:00:00 10
09/03/2005 00:00:00 10
09/04/2005 00:00:00 10
09/05/2005 00:00:00 30
09/06/2005 00:00:00 30
09/07/2005 00:00:00 30
09/08/2005 00:00:00 70
09/09/2005 00:00:00 70
09/10/2005 00:00:00 70
09/11/2005 00:00:00 70
09/12/2005 00:00:00 60
09/13/2005 00:00:00 60
09/14/2005 00:00:00 20
09/15/2005 00:00:00 20
09/16/2005 00:00:00 20
09/17/2005 00:00:00 20
09/18/2005 00:00:00 20
tanqth 2005-09-13
  • 打赏
  • 举报
回复
我试了,这条语句确实可以实现我的功能,只是test表不好处理,理论上是test有多少记录就能统计多少天,
feng2(蜀山风云) 真是高手,
feng2 2005-09-13
  • 打赏
  • 举报
回复
test是一张业务表,主要是为了满足天数统计,如果你当前的业务表够大也可以(上万条记录);

b4:起始日期
b5:终止日期
d:是最小日期
r:是序列(1.2.3.4......)
i:就是结果集中的"日期"
yearlist 2005-09-13
  • 打赏
  • 举报
回复
如果test表存在,那表纪录必须满足>=max(b5)-min(b4)+1吧。
feng2(蜀山风云),真是高人,高不可攀啊
yearlist 2005-09-13
  • 打赏
  • 举报
回复
不明白,test表从何而来?b4(始),b5(终)是日期吧,d,r,i是什么?怎么来的?看了楼上的SQL,我彻底晕了。

17,377

社区成员

发帖
与我相关
我的任务
社区描述
Oracle 基础和管理
社区管理员
  • 基础和管理社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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