Sql 创建一个变量,逐步统计一个ID在一天中重复的次数
因此,我有一个表,它每天有不同的日期和时间,并且客户ID每天可以出现多次Sql 创建一个变量,逐步统计一个ID在一天中重复的次数,sql,sas,proc-sql,Sql,Sas,Proc Sql,因此,我有一个表,它每天有不同的日期和时间,并且客户ID每天可以出现多次 data Data1; infile datalines delimiter=','; input date :ddmmyy10. ID $ time :time8. $ ; format date ddmmyy10.; format time time8.; datalines; 05/11/2020,1000,8:15:23 05/11/2020,1000,8:20:10 05/11/20
data Data1;
infile datalines delimiter=',';
input date :ddmmyy10. ID $ time :time8. $ ;
format date ddmmyy10.;
format time time8.;
datalines;
05/11/2020,1000,8:15:23
05/11/2020,1000,8:20:10
05/11/2020,1001,8:21:10
05/11/2020,1001,9:05:15
05/11/2020,1001,10:30:20
06/11/2020,1002,8:26:10
06/11/2020,1003,8:27:10
06/11/2020,1003,9:40:01
;
我想输出另一个名为“尝试”的列,如下所示:
data Data1;
infile datalines delimiter=',';
input date :ddmmyy10. ID $ time :time8. $ Attempt;
format date ddmmyy10.;
format time time8.;
datalines;
05/11/2020,1000,8:15:23,1
05/11/2020,1000,8:20:10,2
05/11/2020,1001,8:21:10,1
05/11/2020,1001,9:05:15,2
05/11/2020,1001,10:30:20,3
06/11/2020,1002,8:26:10,1
06/11/2020,1003,8:27:10,1
06/11/2020,1003,9:40:01,2
06/11/2020,1000,10:20:10,1
06/11/2020,1000,11:20:10,2
06/11/2020,1000,12:20:10,3
06/11/2020,1000,13:20:10,3
;
如您所见,客户端1000在11月5日出现两次,在11月6日出现4次,客户1001在11月5日出现3次,客户1002在11月6日出现一次,客户1003在11月6日出现2次
我还希望3是最大值,因此,如果一个客户在一天中出现3次以上,如2011年6月的客户1000,则该值为3
我不介意使用sas语言或proc sql,因此如果有人对这两种语言有任何想法,请让我知道只需使用组处理和保留变量即可。您可以使用MIN功能将计数器上限设置为3
data Data1;
infile datalines dsd;
input date :ddmmyy. ID $ time :time. expect;
format date ddmmyy10. time time8.;
datalines;
05/11/2020,1000,8:15:23,1
05/11/2020,1000,8:20:10,2
05/11/2020,1001,8:21:10,1
05/11/2020,1001,9:05:15,2
05/11/2020,1001,10:30:20,3
06/11/2020,1000,10:20:10,1
06/11/2020,1000,11:20:10,2
06/11/2020,1000,12:20:10,3
06/11/2020,1000,13:20:10,3
06/11/2020,1002,8:26:10,1
06/11/2020,1003,8:27:10,1
06/11/2020,1003,9:40:01,2
;
data want;
set data1;
by date id ;
retain attempt;
if first.id then attempt=1;
else attempt=min(3,attempt+1);
run;
注意:我重新排序了您的示例数据,以避免需要添加PROC排序步骤。如果您的真实数据集已分组但未排序(如示例中所示),则可以在BY语句中添加NOTSORTED关键字,逻辑将起作用。只需使用BY group processing和保留变量即可。您可以使用MIN功能将计数器上限设置为3
data Data1;
infile datalines dsd;
input date :ddmmyy. ID $ time :time. expect;
format date ddmmyy10. time time8.;
datalines;
05/11/2020,1000,8:15:23,1
05/11/2020,1000,8:20:10,2
05/11/2020,1001,8:21:10,1
05/11/2020,1001,9:05:15,2
05/11/2020,1001,10:30:20,3
06/11/2020,1000,10:20:10,1
06/11/2020,1000,11:20:10,2
06/11/2020,1000,12:20:10,3
06/11/2020,1000,13:20:10,3
06/11/2020,1002,8:26:10,1
06/11/2020,1003,8:27:10,1
06/11/2020,1003,9:40:01,2
;
data want;
set data1;
by date id ;
retain attempt;
if first.id then attempt=1;
else attempt=min(3,attempt+1);
run;
注意:我重新排序了您的示例数据,以避免需要添加PROC排序步骤。如果你的真实数据集被分组但没有排序,如在你的例子中,你可以在Buby语句中添加NoSoRID关键字,逻辑将工作。 < P>可选的,你仍然可以使用条件相关聚合查询来考虑PROSQL SQL:
data Data1;
infile datalines delimiter=',';
input date :ddmmyy10. ID $ time :time8. ;
format date ddmmyy10.;
format time time8.;
datalines;
05/11/2020,1000,8:15:23
05/11/2020,1000,8:20:10
05/11/2020,1001,8:21:10
05/11/2020,1001,9:05:15
05/11/2020,1001,10:30:20
06/11/2020,1002,8:26:10
06/11/2020,1003,8:27:10
06/11/2020,1003,9:40:01
06/11/2020,1000,10:20:10,1
06/11/2020,1000,11:20:10,2
06/11/2020,1000,12:20:10,3
06/11/2020,1000,13:20:10,3
;
proc sql;
CREATE TABLE output AS
SELECT d.date, d.ID, d.time
, (SELECT CASE
WHEN COUNT(*) > 3
THEN 3
ELSE COUNT(*)
END FROM Data1 sub
WHERE sub.ID = d.ID
AND sub.date = d.date
AND sub.time <= d.time
) AS attempts
FROM Data1 d;
quit;
可选地,您仍然可以使用条件相关聚合查询来考虑PROSQL SQL:
data Data1;
infile datalines delimiter=',';
input date :ddmmyy10. ID $ time :time8. ;
format date ddmmyy10.;
format time time8.;
datalines;
05/11/2020,1000,8:15:23
05/11/2020,1000,8:20:10
05/11/2020,1001,8:21:10
05/11/2020,1001,9:05:15
05/11/2020,1001,10:30:20
06/11/2020,1002,8:26:10
06/11/2020,1003,8:27:10
06/11/2020,1003,9:40:01
06/11/2020,1000,10:20:10,1
06/11/2020,1000,11:20:10,2
06/11/2020,1000,12:20:10,3
06/11/2020,1000,13:20:10,3
;
proc sql;
CREATE TABLE output AS
SELECT d.date, d.ID, d.time
, (SELECT CASE
WHEN COUNT(*) > 3
THEN 3
ELSE COUNT(*)
END FROM Data1 sub
WHERE sub.ID = d.ID
AND sub.date = d.date
AND sub.time <= d.time
) AS attempts
FROM Data1 d;
quit;
使用数据步骤要简单得多。使用数据步骤要简单得多。嗨,谢谢!我用代码片段试过了,效果很好,但当我用真实数据试过时,它只显示了尝试次数=1、2、3。我确实意识到,在我的真实数据中,唯一排序的是日期,但ID没有像代码片段中那样分组,这可能是原因吗?您需要按两者进行排序。proc sort data=data1;按日期id;跑您还可以按id日期使用;但是,请确保测试first.date而不是first.id。要以正确的顺序获取尝试次数,请在排序步骤中包含时间。按id日期时间;。非常感谢。我想这就是我所缺少的:嗨,谢谢!我用代码片段试过了,效果很好,但当我用真实数据试过时,它只显示了尝试次数=1、2、3。我确实意识到,在我的真实数据中,唯一排序的是日期,但ID没有像代码片段中那样分组,这可能是原因吗?您需要按两者进行排序。proc sort data=data1;按日期id;跑您还可以按id日期使用;但是,请确保测试first.date而不是first.id。要以正确的顺序获取尝试次数,请在排序步骤中包含时间。按id日期时间;。非常感谢。我想这就是我们所缺少的: