楼主: lachance
5485 9

[原创博文] 先分组,再取每组中前两条最小的纪录 , 但是纪录不能重复 [推广有奖]

  • 1关注
  • 3粉丝

已卖:3份资源

讲师

44%

还不是VIP/贵宾

-

威望
0
论坛币
693 个
通用积分
0.0157
学术水平
4 点
热心指数
5 点
信用等级
1 点
经验
10072 点
帖子
403
精华
0
在线时间
399 小时
注册时间
2008-1-22
最后登录
2020-4-15

楼主
lachance 发表于 2011-3-5 07:39:22 |AI写论文

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

求职就业群
赵安豆老师微信:zhaoandou666

经管之家联合CDA

送您一个全额奖学金名额~ !

感谢您参与论坛问题回答

经管之家送您两个论坛币!

+2 论坛币
先分组,再取每组中前两条最小的纪录

表结构如下:
a        b        c
s1        d3        0
s1        d1        2
s1        d2        3


s2        d3        0
s2        d1        1
s2        d4        2

s2        d5        7
s2        d6        8

s3        d3        1
s3        d1        1
s3        d2        2
s3        d4        0.5

s3        d5        0.5
s3        d7        8
s3        d9        12

先按照字段a分组,再取每组中c字段的前两条最小的纪录,也就是说,
对s1组,应该取

s1        d3        0
s1        d1        2
因为这两条的c字段纪录值最小.


对s2组,本应该取
s2        d3        0
s2        d1        1
但是因为字段b的d3, d1已经在s1组中出现过,

所以只能取
s2        d4        2
s2        d5        7



同样对s3组,本该取
s3        d4        0.5
s3        d5        0.5
但是d1,d3,d4,d5都在前面的两组中出现了,所以只能取两个最小的c字段值.
s3        d2        2
s3        d7        8


用了下面的SQL ,
Select *
From test A
Where (Select Count(*)
           From test
           Where a = A.a And c< A.c) < 2
Order By a, c



只能实现取每组前两个最小的c纪录值.
请问如何实现b字段已经出现在其他组中就不参与分组排序的PROC SQL,

想用宏来实现出现过就删除, 但不知道大家有没有好的办法?


请高手帮忙,多谢
二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

关键词:proc sql Select Where Elect Count

回帖推荐

ntsean 发表于4楼  查看完整内容

可以用data step data test; input a $ b $ c; datalines; s1 d3 0 s1 d1 2 s1 d2 3 s2 d3 0 s2 d1 1 s2 d4 2 s2 d5 7 s2 d6 8 s3 d3 1 s3 d1 1 s3 d2 2 s3 d4 0.5 s3 d5 0.5 s3 d7 8 s3 d9 ...

本帖被以下文库推荐

沙发
webgu 发表于 2011-3-5 08:18:35
但是字段d1 也在S1组中已出现过了。

藤椅
lachance 发表于 2011-3-5 09:04:41
谢谢,我再改改我的数据表.
[

板凳
ntsean 发表于 2011-3-5 09:19:07
可以用data step

data test;
input a $ b $ c;
datalines;
s1        d3        0
s1        d1        2
s1        d2        3
s2        d3        0
s2        d1        1
s2        d4        2
s2        d5        7
s2        d6        8
s3        d3        1
s3        d1        1
s3        d2        2
s3        d4        0.5
s3        d5        0.5
s3        d7        8
s3        d9        12
;run;

proc sort data=test;
by a c;run;

data sorted(drop=bstring count);
length bstring $200.;
set test;
by a;
if first.a then count=0;
if (count<2 and index(bstring,trim(b))=0) then do;
output;
count+1;
bstring=cat(trim(left(bstring)),b);
end;
retain bstring;

proc print data=sorted;run;
已有 1 人评分学术水平 收起 理由
飘洒 + 1 很巧妙啊!

总评分: 学术水平 + 1   查看全部评分

报纸
lachance 发表于 2011-3-5 21:56:05
非常感谢回复!
但是如果数据量有几千万条, bstring 的长度就不够了.
The length of character var is 1-32767.
[

地板
ntsean 发表于 2011-3-6 09:25:37
这个如何?


data test;
input a $ b $ c;
datalines;
s1        d3        0
s1        d1        2
s1        d2        3
s2        d3        0
s2        d1        1
s2        d4        2
s2        d5        7
s2        d6        8
s3        d3        1
s3        d1        1
s3        d2        2
s3        d4        0.5
s3        d5        0.5
s3        d7        8
s3        d9        12
;run;

proc sort data=test out=testgp;
by a c;

data testgp;
set testgp;
by a;
if first.a then group+1;
call symput("ngroup", group);
run;

%macro getmin2;
data new;
set testgp;
if group=1;

data min2;
set new(obs=2);
run;

%do i=2 %to &ngroup;
proc sql;
create table new as
select * from testgp where group=&i and b not in (select b from min2);

data min2;
set min2 new(obs=2);
run;
%end;
%mend;
%getmin2;

proc print data=min2;run;

5# lachance
已有 1 人评分学术水平 热心指数 信用等级 收起 理由
lachance + 1 + 1 + 1 It's highly appreciated ;-)

总评分: 学术水平 + 1  热心指数 + 1  信用等级 + 1   查看全部评分

7
lachance 发表于 2011-3-7 10:23:25
非常感谢ntsean, 这个方法也很巧妙呀。
[

8
潇湘夜雨spp 发表于 2014-3-26 09:50:16
崇拜各种牛牛

9
soporaeternus 发表于 2014-3-26 11:11:49
  1. data b;
  2.         if _n_ = 1 then do;
  3.                 declare hash h();
  4.                 declare hiter i('h');
  5.                 rc = h.defineKey('b');
  6.                    rc = h.defineData('b');
  7.                    rc = h.defineDone();
  8.         end;
  9.         set a;by a c;
  10.         if first.a then _N=0;
  11.         if _N<2 then do;
  12.         rc=h.find();
  13.                 if rc^=0 then do;
  14.                         _N+1;
  15.                         rc=h.add();
  16.                         output;
  17.                 end;
  18.         end;
  19.         drop _N rc;
  20. run;
复制代码
Let them be hard, but never unjust

10
learsaas 发表于 2014-4-1 09:34:08 来自手机
手写的代码,手头没工具调试,楼主根据我的思路自己调试:
%macro getmintwo;
    Proc sort data=a out=x;
        By a c;
    Run;
    Data temp result;
        Set x;
        Stop;
    Run;
    Proc Sql;
        Select count(distinct(a)) into :n from x;
    Quit;
    %do I=1 %to &in;
        Data x;
            Set x;
            If _n_=1 then do;
                Declare hash myhash('temp');
                Myhash.definekey('b');
                Myhash.definedone();
            End;
            Rc=myhash.check();
            If rc^=0;
            Drop rc;
        Run;   
        Data temp x;
            Set x;
            By a c;
            If first.a then do;n+1;m=0;end;
            M+1;
            If n=1 and m<=2 then output temp;
            Else if n>=2 then output x;
            Drop n m;
        Run;
        Proc append base=result data=temp;
        Run;
        Proc SQL;
             Select count(*) into :j from x;
        Quit;
        %if &j eq 0 %then %goto exit;
    %end;
    %exit:
%mend;
%getmintwo;

您需要登录后才可以回帖 登录 | 我要注册

本版微信群
加好友,备注cda
拉您进交流群
GMT+8, 2026-1-4 08:26