【问题标题】:How do i get the date from a min and max group by?我如何从最小和最大组中获取日期?
【发布时间】:2018-10-11 09:29:55
【问题描述】:

我是一名 SAS 开发人员。 我有一个 sql 用于从名为“CalculatedPower”的列中获取最小值和最大值。 下面是我从 group by 语句中得到的结构 (lt_dt 和 lp_dt 是我想要的。我把它放在这里,但它不在我的实际表中,因为我不知道如何实现这一点) :

station datetime        calculatedpower min_power   max_power   lt_dt               lp_dt
ABBA    28AUG2018:0:0:0     100         1            100        01SEP2018:1:0:0     28AUG2018:0:0:0
ABBA    31AUG2018:12:0:0    88          1            100        01SEP2018:1:0:0     28AUG2018:0:0:0
ABBA    01SEP2018:1:0:0     1           1            100        01SEP2018:1:0:0     28AUG2018:0:0:0
ZZZZ    07SEP2018:0:0:0     900         900          3000       07SEP2018:0:0:0     21SEP2018:0:0:0
ZZZZ    09SEP2018:0:0:0     1000        900          3000       07SEP2018:0:0:0     21SEP2018:0:0:0
ZZZZ    21SEP2018:0:0:0     3000        900          3000       07SEP2018:0:0:0     21SEP2018:0:0:0

正如大家所见,我将它们按 Station 聚合并使用 Min 和 Max 函数来获取 min_power 和 max_power。现在,我还需要获取最小日期时间(进入 lt_dt)和最大日期时间(进入 lp_dt)。 我会期待如下: ABBA lt_dt 是 01SEP2018:1:0:0 而 lp_dt 是 28AUG2018:0:0:0

意思是lp_dt(datetime based on max_power) 而lt_dt(datetime based on min power)

我的分组声明如下:

proc sql;
select 
station
,datetime
,calculatedpower
,min(calculatedpower) as lt_calculatedpower
,max(calculatedpower) as lp_calculatedpower
from sumall
group by 
station
;
quit;

有没有办法调整我现有的 SQL 语句以实现我想要的日期时间? 我尝试了如下所示的附加 SQL 语句(但处理 600k 数据需要很长时间,不确定它是否有效,因为它仍在运行)

proc sql;
select *,
case when calculatedpower=lt_calculatedpower then datetime end as lt_datetime
from minmax;
quit;

使用此代码,我预计如果有几行具有相同的计算功率但与 1 个站点相关的日期时间不同,则会出现问题。

【问题讨论】:

  • 为什么不简单地将 max(datetime) 作为 lt_dt 并与 min 相同?我错过了什么?
  • lp_dt 是基于 max_power 的日期时间,而不是最大日期时间。如果 max_power 在第 2 行,lp_dt 应该是第 2 行的 1。因此, max(datetime) 不会得到我想要的结果。
  • 一定要用SQL吗?带有 ID 的 PROC Summary 是一个不错的选择或数据步骤。
  • @Reeza 你能提供一些样本吗?我以前从未使用过 PROC Summary。
  • 如果有多个不同的日期,calculatedpower = maxpower 对应同一个station,你想选择哪个日期?

标签: sql sas


【解决方案1】:

在 SQL 中,您将需要使用包含 case 语句的子选择,该语句标识最小值和最大值出现的日期。子选择连接到原始表。

注意:SAS SQL 将在适当时自动重新加入汇总(聚合函数)结果。

示例

在此示例中,level1_id 用于stationlevel2_seq 用于datetimex 用于calculatedpower

data have;
  do level1_id = 1 to 5;
    do level2_seq = 1 to 5;
      x = floor(100*ranuni(123));
      output;
    end;
  end;
run;

proc sql;
  create table want as
  select 
    have.*
    , min(have.x) as min_x
    , max(have.x) as max_x
    , min(at.min_at) as min_x_first_at_seq
    , min(at.max_at) as max_x_first_at_seq
  from 
    have
  left join 
  (
    select inside.level1_id, inside.level2_seq
    , case when inside.x = min(inside.x) then inside.level2_seq else . end as min_at
    , case when inside.x = max(inside.x) then inside.level2_seq else . end as max_at
    from have inside
    group by inside.level1_id
  ) at
  on
    have.level1_id = at.level1_id and
    have.level2_seq = at.level2_seq
  group by
    have.level1_id
  order by
    have.level1_id, level2_seq
  ;

【讨论】:

    【解决方案2】:

    这是 SAS PROC Summary 和 DATA STEP 合并,以获得最终所需的输出。

    使用 OUTPUT 语句中的 MAXID、MINID 选项来获取最大值的 ID 和最小值的 ID。

    解决方案的第一部分会生成您的虚假数据 - 请在以后提供该格式的数据。然后 PROC Summary 计算统计数据,您可以将其合并。这应该在您的系统上非常快地完成,不到一分钟。

    data have;
    input station $ datetime  anydtdtm.      calculatedpower ;
    format datetime datetime.;
    cards;
    ABBA    28AUG2018:0:0:0     100         
    ABBA    31AUG2018:12:0:0    88          
    ABBA    01SEP2018:1:0:0     1           
    ZZZZ    07SEP2018:0:0:0     900         
    ZZZZ    09SEP2018:0:0:0     1000        
    ZZZZ    21SEP2018:0:0:0     3000        
    ;;;;
    run;
    
    proc summary data=have nway;
    class station;
    id datetime;
    var calculatedPower;
    output out=summary min=Min_power max=max_power minid=min_date  maxid=max_Date;
    run;
    
    data final;
    merge have summary;
    by station;
    run;
    

    编辑:删除了自动命名选项,因为我明确命名了输出变量。

    编辑2: 当多个观测值在所有 MIN 或 MAX 变量中包含相同的极值时,PROC MEANS 使用观测值来确定将哪个观测值写入输出。 默认情况下,PROC MEANS 使用第一个观察值来解决任何关系。但是,如果您指定 LAST 选项,则 PROC MEANS 使用最后一个观察值来解决任何关系。

    https://documentation.sas.com/?docsetId=proc&docsetTarget=p04vbvpcjg2vrjn1v8wyf0daypfi.htm&docsetVersion=9.4&locale=en#p1p58yhxlrc0can1scam7bco7y96

    【讨论】:

    • 我试过你的代码。它给了我想要的结果。但是,进一步询问,如果我的 ABBA 站有大约 100 条记录,并且恰好在 10 个不同的日期具有相同的 max_power。它可以给我首先出现的 max_power 的日期时间吗?
    • 尝试相应地对您的数据进行排序并再次尝试 proc 摘要。
    猜你喜欢
    • 1970-01-01
    • 2019-01-11
    • 2022-10-13
    • 1970-01-01
    • 2017-02-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多