SAS在proc sql vs proc中排除了nodupkey

时间:2014-01-21 10:26:59

标签: sql sorting sas distinct proc

我有以下数据集:

data work.dataset;
input a b c;
datalines;
27 93 71 
27 93 72
46 68 75
55 55 33
46 68 68
34 34 32
45 67 88
56 75 22
34 34 32
;
run;

我想从前两列中选择所有不同的记录,所以我写道:

proc sql;
create table work.output1 as
select distinct t1.a,
t1.b
from work.dataset t1;
quit;

但是现在我想知道var c在输出中看到的组合(var a,var b)旁边的前一个集合中的值。有没有办法找出来?我试过跟踪proc排序,但我不知道它是否与在proc sql中选择不同记录的方式相同。

proc sort data = work.dataset out = work.output2 NODUPKEY;
by a b;
run;

提前感谢您的帮助。

3 个答案:

答案 0 :(得分:3)

带有PROC SORT

NODUPKEY将始终返回实际的第一条记录 - 即,当您列出数据时,c=71将始终保留。 PROC SQL不一定会返回任何特定记录;您可以要求minmax,但无论您如何进行查询,都无法保证排序顺序中的第一条记录; SQL通常会根据需要使用数据来尽可能高效地完成查询。

他们将是相同的,因为他们都返回相同数量的记录,如果这是您的关注。

你无法在SQL中以直截了当的方式完成同样的事情;因为SQL没有行排序的概念,你必须要么有一个方法来选择哪个c(max(c)min(c)等),或者你必须添加一个行计数器和选择最低值。

例如:

data work.dataset;
input a b c;
rowcounter=_n_;
datalines;
27 93 71 
27 93 72
46 68 75
55 55 33
46 68 68
34 34 32
45 67 88
56 75 22
34 34 32
;
run;

proc sql;
select a,b,min(rowcounter*100+c)-min(rowcounter*100) as c
from work.dataset
group by a,b;
quit;

那是使用作弊(知道行计数器* 100将始终支配c的大小);当然,如果你的c没有适合的价值,那么这将不起作用,你最好将其单独合并。

如果您对SQL解决方案感兴趣,可以考虑将其明确地作为单独的问题发布,因为只有SQL的人才会回答它。

答案 1 :(得分:1)

NODUPKEY将为每个键返回一个观察值。在您的示例中,只保留a = 27和b = 93的两个观测值中的一个。 c = 71或c = 72将会丢失。

NODUPREC选项将删除重复记录。将保留a = 27和b = 93的两个观测值,但两个中只有一个具有值a = 34,b = 34和c = 32。

答案 2 :(得分:0)

Sql不会在上面的查询中返回变量c的值,因为它没有在select语句中列出。我想你可能在寻找的是:

proc sql;
create table work.output1 as
select t1.a,
t1.b,
min(t1.c) as c
from work.dataset t1
group by a, b;
quit;

如果您希望c的最大值,则可以使用max(t1.c) as c替换该函数,或使用任何其他sql函数来选择您的值。如果你想要复制PROC SORT nodupkey,并取下列出的第一个值,你需要使用单调函数(我知道......不支持SAS,但它就是那里的东西)。您的代码现在是:

proc sql;
create table work.output1 as
select monotonic() as rownum,
t1.a,
t1.b,
t1.c
from work.dataset t1
group by a, b
having calculated(rownum) = min(calculated rownum);
quit;