sql—如何将序列号添加到一组特定的连续记录中?

xurqigkl  于 2021-07-29  发布在  Java
关注(0)|答案(5)|浏览(442)

我有个棘手的问题:
这是我的示例数据。它是按日期变量排序的(这里不包括日期变量)。我想计算一个新变量,名为seq\ u no,它为每个连续标记的记录创建一个分组序列号。seqno变量应该和示例中的一样,我想用sas或sql来计算它。

ID flag seq_no
1   Y      1
1
1   Y      2
1   Y      2
2
2   Y      1
2   Y      1
2
2   Y      2
3   Y      1
3   Y      1
3

提前多谢了!斯蒂芬

qhhrdooz

qhhrdooz1#

与sas数据集不同,sql表表示无序集。下面假设您有一列指定顺序。
您可以在每个“y”之前计算空记录的数量,并使用它来指定唯一的值:

proc sql;
    select t.*,
           (select count(*)
            from t t2
            where t2.id = t.id and t2.flag is null and t2.ordcol <= t.ordcol
           ) grp_id
    from t;

一个“真正的”数据库将具有更重要的功能——特别是窗口功能——这将促进这项工作。

jgzswidk

jgzswidk2#

正如您所说的,它是按日期变量排序的(这里不包括),这是一种使用窗口聚合的方法,大多数DBMSE都支持:

with cte as 
 ( select id, flag, datecol,
      -- assign a new value whenever there's a NULL flag 
      sum(case when flag is null then 1 else 0 end)
      over (partition by id
            order by datecol
            rows unbounded preceding) as grp
   from tab
 )
select id, flag, datecol, grp,
   case when flag is not null
   then dense_rank() -- assign a sequence to each group of 'Y'
        over (partition by id
              order by grp)
   end
from cte

如果你不在乎序列是从0开始还是从1开始,你甚至可以把它简化为

select id, flag, datecol,
   case when flag is not null
   then sum(case when flag is null then 1 else 0 end)
        over (partition by id
              order by datecol
              rows unbounded preceding)
   end as grp2
from tab
6jjcrrmo

6jjcrrmo3#

sql不是一个很好的工具,因为它是为集合操作而设计的,而不是顺序处理(其他sql实现中有一些变通方法和高级函数可以提供帮助,请参阅其他答案。)
但在数据步骤中,使用保留变量很简单。

data want;
  set have;
  by id ;  
  if first.id then seq_no=0;
  seq_no+(flag='Y');
run;

您请求中的一个问题是,您不希望在标志不是y的记录上进行计数。使用一个单独的变量来保留计数比使用“seq\u no”变量更容易做到这一点。

data want;
  set have;
  by id ;  
  if first.id then cumm_seq_no=0;
  cumm_seq_no+(flag='Y');
  if flag='Y' then seq_no=cumm_seq_no;
run;
w46czmvw

w46czmvw4#

下面是一个基本的sas方法。

proc sort data=have; 
   by id date;

data want (drop=prev_seq);
   set have;
   by id;
   retain prev_seq;
   if first.id then prev_seq = .;
   if flag = 'Y' then do;
      prev_seq + 1;  
      seq_no = prev_seq;
   end;
run;
mzillmmw

mzillmmw5#

你想要什么 seq_no 在连续的 Yflag 价值观。使用 NOTSORTED 选择 BY 语句处理连续块,当块无序或有间隙时。
例子:

data want;
  set have;
  by id flag NOTSORTED;

  if first.id then seq_num = 0;
  if first.flag and flag = 'Y' then seq_num+1;

  if flag='Y' 
    then seq_no = seq_num;
    else call missing(seq_no); 

  drop seq_num;
run;

相关问题