Sql 创建一个变量,逐步统计一个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

因此,我有一个表,它每天有不同的日期和时间,并且客户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/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日期时间;。非常感谢。我想这就是我们所缺少的: