data emp;
input empID;
cards;
2
3
2
4
3
5
3
2
run;
我想编写proc sql delete query来删除所有重复记录但保留一个以便数据集只有以下记录。我想使用删除查询来做,不想创建表
empID
2
3
4
5
我试过这个但是没有用。
proc sql;
delete from emp where empid in
( select t.empid from emp t where t.empid=empid
group by t.empId having count(t.empid)>2
);
quit;
答案 0 :(得分:4)
我不认为SAS proc sql
有任何关于" rownum"的概念。专栏或" ctid"柱。因此,最简单的方法是创建一个新的数据集:
proc sql;
create table emp2 as
select distinct empid
from emp;
答案 1 :(得分:0)
使用proc sort
和nodup
选项有什么问题?
proc sort data=emp nodup;
by empid;
run;
第二个答案:
如果您无法直接或使用proc sort
创建表格,那么我相信您唯一的选择是使用带有modify
语句的数据步骤。这会更新现有数据集,而不是创建新数据集并在代码成功运行时替换现有数据集。
由于您的数据似乎未分类,因此需要采用更具创造性的方法,而不是可以使用排序数据完成的简单first.empid
。我所做的是在读取数据集时建立一个唯一值列表,然后查找该列表中的当前值。如果存在则删除该行。由于_list
不允许添加新字段,因此无需删除我创建的临时字段(modify
),它仅在后台使用。
请注意,以这种方式删除记录(并使用delete from
中的proc sql
语法)并未实际删除记录,只是将其标记为已删除,因此他们不会删除记录查看或查询时出现。如果在运行代码后打开Emp数据集,您将看到缺少行号。
data emp;
modify emp;
length _list $200; /* set length of temporary field */
retain _list; /* retain existing values */
if findw(_list,strip(empid))>0 then remove; /* delete observation if empid already exists */
else call catx(',',_list,empid); /* add current empid to list if it doesn't already exist */
run;
我应该补充一点,这个答案的可扩展性不是很高,例如:如果您有一个包含许多唯一值的大型数据集,那么_list变量将需要非常长的长度来容纳它们。如果EmpId对Emp数据集进行排序或至少索引,则更好的选择。这样你可以执行以下操作(emp在set
语句中包含两次,因为by
语句仅在set
语句中有2个数据集时才有效。这是一个技巧启用first.
处理。)
data emp;
modify emp (obs=0) emp;
by empid;
if not first.empid then remove;
run;