【问题标题】:Converting CYYMMDD to SAS Date in DB2 via SAS通过 SAS 在 DB2 中将 CYYMMDD 转换为 SAS 日期
【发布时间】:2013-02-18 10:21:07
【问题描述】:

我希望将 CYYMMDD 格式的日期(其中 C 为 20 世纪的 0 或 21 世纪的 1)转换为标准 SAS 日期。此代码将使用“proc sql”放置在 SAS 查询中,以便它可以将 SAS 日期与存储在 DB2 中的日期进行比较。

示例:输入数据=1130101,输出='1Jan2013'd

我试过的例子是:

(substr(t1.'EffectDate'n,4,2)|| '/' || substr(t1.'EffectDate'n,6,2) || '/' || cast(substr(t1.'EffectDate'n,1,3) AS INTEGER) + 1900)

cast() 函数失败(似乎不存在?)

也试过了:

convert(varchar(10), convert(datetime, right(t1.'EffectDate'n, 6), 12), 101)

但是 varchar(10) 不存在。

我的查询如下所示:

proc sql;
create table CLAIMS as select
          t1.CID, 
          t1.MID, 
          t1.DOS 
          OTHER_TABLE.ChangeDate AS EffectDate
      FROM
        SOURCE.REJECTED t1
      INNER JOIN
        EGTASK.OTHER_TABLE
      ON
        t1.DOS >= *Converted_Date*
      [... goes on a couple more lines...]

*Converted_Date* 是我需要的。

(但是,我应该澄清一下,这个特定的查询/连接不一定需要是 SQL)

【问题讨论】:

  • 首先,不需要用单引号和n 限定符将SAS 变量名括起来; EffectDate 很好。它是什么类型的变量(字符或数字)?
  • 引号是玩弄后留下的——只是在那个声明中是这样的。变量是数字。它采用“示例”中列出的输入数据的格式
  • 对不起,这太复杂了,但是两个 LIBREFS “SOURCE”和“EGTASK”指的是什么?它们是不同的 DB2 连接还是一个 SAS 库?
  • EGTASK 只是一个存储临时表的地方(EG 指的是 Enterprise Guide,一个 SAS GUI 程序)。在这种情况下,“SOURCE”不是外部引用,抱歉——它是一个 SAS 库(我在最初的问题中指出,这一切都不一定是 SQL——我最初没有记住这一点)。我现在收到以下错误:错误:使用大于或等于 (>=) 的表达式具有不同数据类型的组件。错误:在贡献表中未找到以下列:SASEffectDate。
  • 好的,然后看看我更新的答案。它向您展示了如何在 CASE 表达式中操作这些变量。只需修改它以在您的主 SQL 中创建一个派生表(即INNER JOIN (SELECT ...)。请注意,您现在说您的问题是 100% SAS 并且根本不涉及 DB2。

标签: sql db2 sas


【解决方案1】:

要将变量从当前编码格式转换为正确的 SAS 日期变量,您需要将其转换为字符串,然后使用 INPUT 函数读取结果。例如:

data _null_;
  do EffectDate = 1130101,0130101;

     cEffectDate = put(EffectDate,z7.);
     if substr(cEffectDate,1,1) = '0'
         then SASEffectDate = input('19' || substr(cEffectDate,2),yymmdd8.);
         else SASEffectDate = input('20' || substr(cEffectDate,2),yymmdd8.);
     put EffectDate=
       / SASEffectDate=
       / ;
     end;
  format SASEffectDate yymmdd10.;
run;

这只是一个插图,有点啰嗦;它创建一个名为 SASEffectDate 的新 SAS 变量以保留原始变量。将其作为 SAS 变量后,您无需执行任何其他操作; SAS Access 产品将知道如何引用外部数据库。

这是一个使用PROC SQL 做类似事情的例子:

data have; /* Just a dummy data set for illustration */
  do EffectDate = 1130101,0130101;
     i+1;
     output;
     end;
run;
proc sql;
   create table want as
   select t2.*
        , case when t2.EffectDate < 999999 /* starts with 0 */
             then input('19' || substr(put(EffectDate,z7.),2),yymmdd8.)
             else input('20' || substr(put(EffectDate,z7.),2),yymmdd8.)
             end as SASEffectDate format=yymmdd10.
    from have t2
    ;
quit;  

【讨论】:

  • 有趣。它究竟是如何集成到 JOIN 语句中的(在 ON 标准中)?此外,正在运行的代码不是 SAS,而是通过“proc sql”从外部数据源提取的 SQL。
  • 我想我很困惑。 EffectDate 是 DB2 表中的列还是 SAS 数据集中的变量?
  • EffectDate 是我的 DB2 表中的一列。
  • 哦;您可以更改您的问题并显示您尝试运行的查询类型吗?听起来您需要在本机 DB2 代码中使用PROC SQL“pass-through”来执行此操作,对吗?
  • 不要忘记将您的聊天结果移动到后代的答案中:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-30
  • 1970-01-01
  • 1970-01-01
  • 2014-08-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多