为唯一会话创建变量

时间:2013-09-10 15:58:12

标签: sql sas proc-sql

我有一些关于人们收听收音机的时间,时长和频道的数据。我需要创建一个名为sessions的变量,它对收音机打开时发生的所有条目进行分组。因为数据可能包含一些错误,我想说,如果从一个通道周期结束到下一个通道周期不到五分钟,那么它仍然是同一个会话。希望一个简短的例子可以澄清。

  obs  Entry_date   Entry_time  duration(in secs) channel
   1    01/01/12      23:25:21    6000               2
   2    01/03/12      01:05:64     300               5
   3    01/05/12      12:12:35     456               5
   4    01/05/12      16:45:21     657               8

我想创建变量会话以便

obs  Entry_date   Entry_time  duration(in secs) channel   session
   1    01/01/12      23:25:21    6000               2    1
   2    01/03/12      01:05:64     300               5    1
   3    01/05/12      12:12:35     456               5    2
   4    01/05/12      16:45:21     657               8    3

用于定义1个会话我需要使用entry_time(如果从晚上11点到第二天早晨,则为日期),以便如果entry_time + duration +(5minutes)< entry_time(下一个频道)然后会话改变。这已经杀了我,简单的数组不会做这个技巧,或者我使用数组的尝试没有用。提前致谢

2 个答案:

答案 0 :(得分:1)

希望我的要求合适! 由于您需要将结果基于相邻的行,因此需要将表连接到自身。 Session #s不是连续的,但你应该明白这一点。

 create table #temp
 (obs int not null,
entry_date datetime not null,
duration int not null,
channel int not null)


--obs  Entry_date   Entry_time  duration(in secs) channel
insert #temp
select   1, '01/01/12 23:25:21', 6000, 2
 union all select 2, '01/03/12 01:05:54', 300, 5
 union all select 3, '01/05/12 12:12:35', 456, 5
 union all select 4, '01/05/12 16:45:21', 657, 8

select a.obs,
       a.entry_date,
       a.duration,
endSession = dateadd(mi,5,dateadd(mi,a.duration,a.entry_date)),
a.channel,
b.entry_date,
minOverlapping = datediff(mi,b.entry_date,
                          dateadd(mi,5,dateadd(mi,a.duration,a.entry_date))),
anotherSession = case 
          when dateadd(mi,5,dateadd(mi,a.duration,a.entry_date))<b.entry_date
    then b.obs
    else a.obs end
from #temp a
  left join #temp b on a.obs = b.obs - 1

希望这有点帮助

答案 1 :(得分:1)

除了我在OP中所做的评论之外,我还将使用SAS数据步骤来实现这一点。我已经将第2行的日期和时间值更改为我怀疑它们应该是什么(为了获得与OP中相同的结果)。这避免了必须执行自联接,这可能是对大型数据集的性能密集 我已经使用了DIF和LAG函数,因此如果你要添加额外的代码(特别是IF语句),需要小心。

data have;
input entry_date :mmddyy10. entry_time :time. duration channel;
format entry_date date9. entry_time time.;
datalines;
01/01/2012 23:25:21 6000 2
01/02/2012 01:05:54 300 5
01/05/2012 12:12:35 456 5
01/05/2012 16:45:21 657 8
;
run;

data want;
set have;
by entry_date entry_time; /* put in to check data is sorted correctly */
retain session 1; /* initialise session with value 1 */
session+(dif(dhms(entry_date,0,0,entry_time))-lag(duration)>300); /* increment session by 1 if time difference > 5 minutes */
run;
相关问题