被一个时间问题弄得头晕,再来娘家求救。

[复制链接]
查看11 | 回复9 | 2014-7-19 06:00:12 | 显示全部楼层 |阅读模式
本帖最后由 limpid00 于 2016-6-2 14:17 编辑
数据是这样的原始表 T:


QQ图片20160602090140.png (12.69 KB, 下载次数: 3)
下载附件
2016-6-2 09:02 上传

callnum,用户电话号码,有重复来电
begin_time,用户拨打电话的开始时间,周期是一个月的
callid,用户拨打该通电话的标识(唯一)
现在的需求是,从用户首次拨打电话后的24小时内,一共的来电次数。
根据需求:
1、找出号码首次拨打的时间
create table T1 as

select callnum,min(begin_time)begin_time from T group by callnum,
2、create table T2 as

select * from T where exists (

select * from T1 where T.callnum=T1.callnum and T.begin_time between T1.begin_time and T1.begin_time+1);
3、select callnum,count(callid) from T2 group by callnum,
得出用户号码从第一次拨打开始的第一个24小时内的来电次数
我比较笨的方法就是,T3=select*from T minus select * from T2,
然后按照上面的方法继续一遍,得出第二个24小时内各号码的来电次数,
但总的周期是一个月,可能存在30遍,按此方法可以求出,但效率太慢,所以来此求教,怎么处理这个循环。

~~~~~~~~~~~~分割线~~~~~~~~~~~~~~~~~
感谢论坛里的朋友无私帮助
后来我又想起另外一种方法来处理,就是增加一列:层级
就是先将表按时间条件分割成若干层级,
例如
第一层:第一次来电到24小时内的所有来电
第二层:除去第一个24小时内的所有来电,余下的首次来电到24小时内
....
依此类推,最后每一行都有标注层级。
那么,最后计算count,
就是select cj,callnum,count(callid) from T group by cj,callnum.得解!


回复

使用道具 举报

千问 | 2014-7-19 06:00:12 | 显示全部楼层
用开窗函数,通过时间开控制开窗范围
回复

使用道具 举报

千问 | 2014-7-19 06:00:12 | 显示全部楼层
chengccy2010 发表于 2016-6-2 09:26
用开窗函数,通过时间开控制开窗范围

貌似在时间的控制上,还是不知道何去何从。
回复

使用道具 举报

千问 | 2014-7-19 06:00:12 | 显示全部楼层
WITH TMP AS
(SELECT MOD(LEVEL, 2) AS CALLNUM, SYSDATE + LEVEL / 24 AS BEGIN_TIME,
LEVEL AS CALLID
FROM DUAL
CONNECT BY LEVEL <= 100)
SELECT T.*,
COUNT(*) OVER(PARTITION BY CALLNUM ORDER BY BEGIN_TIME RANGE BETWEEN CURRENT ROW AND INTERVAL '24' HOUR FOLLOWING) AS C
FROM TMP T

回复

使用道具 举报

千问 | 2014-7-19 06:00:12 | 显示全部楼层
first_value 这个函数,可以吗?
回复

使用道具 举报

千问 | 2014-7-19 06:00:12 | 显示全部楼层
begin_time,周期是一个月的.
什么意思?

回复

使用道具 举报

千问 | 2014-7-19 06:00:12 | 显示全部楼层
chengccy2010 发表于 2016-6-2 09:47
WITH TMP AS
(SELECT MOD(LEVEL, 2) AS CALLNUM, SYSDATE + LEVEL / 24 AS BEGIN_TIME,
LEVEL...


跑起来效率差点。
回复

使用道具 举报

千问 | 2014-7-19 06:00:12 | 显示全部楼层
jxc_hn 发表于 2016-6-2 10:29
begin_time,周期是一个月的.
什么意思?

场景就是,所有用户在一个月内呼叫10086的情况,记录了呼叫号码,呼叫时间,以及每一通通话的标识,可以理解为录音编号,而这份数据是在一个月内的记录。截图只是说明字段构造。
回复

使用道具 举报

千问 | 2014-7-19 06:00:12 | 显示全部楼层
SELECT * FROM (
SELECT
CALLNUM,
COUNT(CALLNUM)OVER(PARTITION BY CALLNUM ORDER BY BEGIN_TIME RANGE BETWEEN CURRENT ROW AND 1 FOLLOWING ) CALL_CT,
ROW_NUMBER()OVER(PARTITION BY CALLNUM ORDER BY BEGIN_TIME) RN
FROM T
)WHERE RN = 1
有个问题 如果客户第一次拨打电话是2016-06-02 11:02:00那2016-06-03 11:02:00 也会统计进去 这个应该是24小时范围的边界上了

回复

使用道具 举报

千问 | 2014-7-19 06:00:12 | 显示全部楼层
yundesishen 发表于 2016-6-2 11:04
SELECT * FROM (
SELECT
CALLNUM,

这个没有关系,就是业务定义的范围。正常来说,那都算是下一个周期了。
类似between...and...
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题

0

回帖

4882万

积分

论坛元老

Rank: 8Rank: 8

积分
48824836
热门排行