求条SQL语句,小弟我做的都想吐了,达人。

求条SQL语句,我做的都想吐了,在线等达人。。数据如下表A:--手机号拨打时间1312012-01-011312012-01-02132201

求条SQL语句,我做的都想吐了,在线等达人。。
数据如下表A:
--手机号         拨打时间     
  131         2012-01-01
  131         2012-01-02
  132         2012-01-05
  133         2012-01-05
  134         2012-01-06
  133         2012-01-06
  135         2012-01-20

需要得到如下结果:表B
--日期        打电话人数   近7天拨打人数
2012-01-01      1           1
2012-01-02      1           1
2012-01-05      2           3
2012-01-06      2           4
2012-01-20      1           1

关键是哪给近7天人数,A表数据量1E左右,请各位朋友给条性能不错的语句。谢谢了。
[最优解释]
习惯性分段处理,这样逻辑也比较清晰,不知道是否满足条件。
如果脚本慢的话,应该是第一个临时表,不过拨打时间应该有索引。

drop table 20121116_test_1;
create table 20121116_test_1 as
select 拨打时间,
       count(1) 打电话人数
  from a
 group by 拨打时间;

drop table 20121116_test_2;
create table 20121116_test_2 as
select a.拨打时间,
       a.打电话人数,
       (select sum(打电话人数)
          from 20121116_test_1
         where 拨打时间>=a.拨打时间-6
           and 拨打时间<=a.拨打时间) 近7天拨打人数
  from 20121116_test_1 a;
[其他解释]
1 优化是技术不是魔法,不是哈利波特拿个小棍一指“快”它就快了。如果你的数据库做了很多无用功(比如可以一行做4个计算解决问题,却遍历了4次,每行只计算一个结果),可以优化。
但是如果数据库选择的是相对合理的方式,做的操作都是必须的步骤,那么慢你也只能忍。

2 具体到这里,一个简单的行转列就可以解决问题,如果还闲慢,那么看能不能建函数索引,如果因为最近7天是个变化值,索引也无效,那么就考虑建立物化视图,因为1亿多数据,真正拨打是35000次还是35001次真的很重要否?不是就牺牲一点点实时性换性能。

3 换我就给表加索引,建物化视图,每天凌晨没有数据进入时用定时任务作收集分析,再慢就让需求方忍着。
[其他解释]
没看懂 你的那个7天的列 咋算的。
[其他解释]

引用:
没看懂 你的那个7天的列 咋算的。




--日期        打电话人数   近7天拨打人数
2012-01-01      1           1   --指131的那个手机号
2012-01-02      1           1   --还是131的手机号
2012-01-05      2           3   --131,132,133这3个手机号
2012-01-06      2           4
2012-01-20      1           1



[其他解释]
你这个表统计的结果就不对吧,近7天拨打的人数应该是7天内所有的拨打的号码数量。比如:今天是2012-01-20,近7天就应该是从[2012-01-14,2012-01-20],这期间的所有电话数量.
[其他解释]
按照我的理解,我写了一个,你看看:
/*DROP TABLE t1;
CREATE TABLE t1(NUM VARCHAR2(11),call_date DATE);

--SELECT * FROM t1;

INSERT INTO t1(NUM,Call_Date) VALUES('131',to_date('2012-01-01','yyyy-mm-dd'));
INSERT INTO t1(NUM,Call_Date) VALUES('131',to_date('2012-01-02','yyyy-mm-dd'));
INSERT INTO t1(NUM,Call_Date) VALUES('132',to_date('2012-01-05','yyyy-mm-dd'));
INSERT INTO t1(NUM,Call_Date) VALUES('133',to_date('2012-01-05','yyyy-mm-dd'));
INSERT INTO t1(NUM,Call_Date) VALUES('134',to_date('2012-01-06','yyyy-mm-dd'));
INSERT INTO t1(NUM,Call_Date) VALUES('133',to_date('2012-01-06','yyyy-mm-dd'));
INSERT INTO t1(NUM,Call_Date) VALUES('135',to_date('2012-01-20','yyyy-mm-dd'));*/
SELECT A.CALL_DATE,
       COUNT(A.NUM) today_num,--当天打电话的人数
       (SELECT COUNT(B.NUM)
          FROM T1 B
         WHERE B.CALL_DATE BETWEEN (A.CALL_DATE - 7) AND A.CALL_DATE) btw7_num --近7天打电话的人数
  FROM T1 A
 GROUP BY A.CALL_DATE
 ORDER BY A.CALL_DATE;
[其他解释]
那个 between(a.call_date -7) 应该是 between(a.call_date -6),  between算的是个闭区间,所以应该是减6天,上面的那个地方写错了,不好意思。
[其他解释]

数据看不懂,,,,
[其他解释]

引用:
按照我的理解,我写了一个,你看看:
/*DROP TABLE t1;
CREATE TABLE t1(NUM VARCHAR2(11),call_date DATE);

--SELECT * FROM t1;

INSERT INTO t1(NUM,Call_Date) VALUES('131',to_date('2012-01-01','yyyy-mm-dd'));
INSERT……


您的这个写法,我有点担忧:
以为表t1的数据量是有1亿条之多,你这样的关联效率会好慢,外加你所有的count()函数里都要加上distinct,这样就更慢了。。。其实我后面还有2个字段没列出来,名字叫做:最近1个月人数,最近3个月人数(字段都是以当前天,向前数1个月,2个月的)。。。
貌似性能相当悲剧哦。。。
[其他解释]
写存储过程吧 亲
[其他解释]
引用:
习惯性分段处理,这样逻辑也比较清晰,不知道是否满足条件。
如果脚本慢的话,应该是第一个临时表,不过拨打时间应该有索引。

drop table 20121116_test_1;
create table 20121116_test_1 as
select 拨打时间,
       count(1) 打电话人数
  from a
 group by 拨打时间;

drop tab……


补充下我的这个方案。
如果是长期都要统计,则第一次建临时表1的时候,是比较杯具的,因为是要处理统计时间点之前的全量数据,但是后续都可以采取增量的方式来处理,估计可以秒。

临时表1出来之后,这个表的数据量最多是万级的,30年总够了,再做子查询就速度很快了。
[其他解释]
貌似都没有什么好的办法啊,只能忍受。。。
[其他解释]
还是那句话,建物化视图,
先把select count(手机号),trunc(时间) from 表 group by trunc(时间)做成物化视图,起码行数少了一千倍不止。

然后再对这个物化视图用几个窗口函数,搞定了。
------其他解决方案--------------------


学习了。forgetsam兄方案不错。
[其他解释]

引用:
1 优化是技术不是魔法,不是哈利波特拿个小棍一指“快”它就快了。如果你的数据库做了很多无用功(比如可以一行做4个计算解决问题,却遍历了4次,每行只计算一个结果),可以优化。
但是如果数据库选择的是相对合理的方式,做的操作都是必须的步骤,那么慢你也只能忍。

2 具体到这里,一个简单的行转列就可以解决问题,如果还闲慢,那么看能不能建函数索引,如果因为最近7天是个变化值……


真心学习了..
感谢
[其他解释]
楼上高手很多啊,真心学习了。
[其他解释]
建第一个表之后的数据就没有办法解决重复号码不能重复计算的问题了吧?
用这个方法明显
数据就变成了这样2012-01-02      1           2
[其他解释]
引用:
习惯性分段处理,这样逻辑也比较清晰,不知道是否满足条件。
如果脚本慢的话,应该是第一个临时表,不过拨打时间应该有索引。

drop table 20121116_test_1;
create table 20121116_test_1 as
select 拨打时间,
       count(1) 打电话人数
  from a
 group by 拨打时间;

drop tab……

这个得不到楼主的效果啊!楼主不是要近7天拨打的电话中同一个号码不能重复计算么?