【问题标题】:SAS: how to properly use intck() in proc sqlSAS:如何在 proc sql 中正确使用 intck()
【发布时间】:2014-12-06 04:38:14
【问题描述】:

我在 SAS 中有以下代码:

proc sql; create table play2 as select a.anndats,a.amaskcd,count(b.amaskcd) as experience from test1 as a, test1 as b where a.amaskcd = b.amaskcd and intck('day', b.anndats, a.anndats)>0 group by a.amaskcd, a.ANNDATS; quit;

数据 test1 有 32 个不同的 obs,而这个 play2 只返回 22 个 obs。我想要做的就是为每个obs,计算历史上相同amaskcd的出现次数。解决这个问题的最佳方法是什么?谢谢。

【问题讨论】:

    标签: sql sas


    【解决方案1】:

    这将返回 22 个观测值(实际上可能与 32 个不同的 22 个观测值)的原因是这是一个逗号连接,在这种情况下它最终基本上是一个内部连接。对于任何给定的行a,如果没有行b 具有后面的anndats 和相同的amaskcd,则不会返回a

    你在这里要做的是左连接,它从a返回所有行一次。

    create table play2
      as select ...
      from test1 a
      left join test1 b
      on a.amaskcd=b.amaskcd
      where intck(...)>0
      group by ...
    ;
    

    我实际上会以不同的方式写这个,因为我不确定上面的内容是否完全符合您的要求。

    create table play2
      as select a.anndats, a.amaskcd,
        (select count(1) from test1 b
           where b.amaskcd=a.amaskcd
           and b.anndats>a.anndats  /* intck('day') is pointless, dates are stored as integer days */
        ) as experience
        from test1 a
        ;
    

    如果您的 test1 还没有按 amaskcd 和 anndats 分组,您可能需要重新设计一些。我怀疑这种子查询更容易编写,并且更准确地反映了您正在尝试做的事情。

    【讨论】:

      【解决方案2】:

      如果每个数据集中的两个 anndats 变量都是日期类型(不是日期时间),那么您可以简单地做一个等号。 SAS 中的日期变量只是整数,其中 1 表示一天。您不需要使用 intck 函数来区分天数,只需使用减法即可。

      我注意到的第二件事是您的代码查找返回 > 0 天。如果第二个值小于第一个值,则 intck 函数可以返回负值。

      我仍然不确定我是否理解您希望在查询中产生什么。它使用 amaskcd 字段作为键连接两个数据集。然后根据 anndats 过滤,只选择 b anndats 值小于 a anndats 或 b.anndats 的记录

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多