繁体   English   中英

SAS:PROC SQL:如何在不创建新列的情况下将字符格式(dd / mm / yyyy)读取为日期格式?

[英]SAS : PROC SQL : How to read a character format (dd/mm/yyyy) as date format without creating new column?

我有一个字符列,其字符格式具有日期(dd / mm / yyyy)。

在应用过滤器(where子句)时,我需要在where语句中将这些字符识别为日期,而无需对现有列进行任何更改或创建新列。

我该如何做到这一点。 任何帮助将不胜感激。

谢谢。

proc sql ,您可以like

select (case when datecol like '__/__/____'
             then . . . 
             else . . .
        end)

这只是一个近似值。 _是一个通配符,可以匹配任何字符,而不仅仅是数字。 另一方面,这是标准SQL,因此可以在任何数据库中使用。

带有?的SAS INPUT功能? informat修饰符会将字符串(源值)转换为结果,并且如果源值与informat不符合,则不会显示错误。

可以在WHERE语句或子句中使用INPUT 输入也可以是BETWEEN语句的一部分。

* some of these free form values are not valid date representations;

data have;
  length freeform_date_string $10;
  do x = 0 to 1e4-1;
    freeform_date_string = 
      substr(put(x,z4.),1,2) || '/' ||
      substr(put(x,z4.),3,2) || '/' ||
      '2018'
    ;
    output;
  end;
run;

* where statement;

data want;
  set have;
  where input(freeform_date_string,? ddmmyy10.);
run;

* where clause;

proc sql;
  create table want2 as
  select * from have
  where 
    input(freeform_date_string,? ddmmyy10.) is not null
  ;

* where clause with input used with between operator operands;

proc sql;
  create table want3 as
  select * from have
  where 
    input(freeform_date_string,? ddmmyy10.) 
    between
      '15-JAN-2018'D
    and
      '15-MAR-2018'D
  ;
quit;

将日期存储为字符值不是一个好主意,它可能导致很多与数据准确性有关的问题,并且您甚至可能都不知道很长一段时间以来都存在数据问题。 说某人输入错误的字符日期,您甚至可能不知道。 最好将日期保持为日期值而不是字符值

在您的代码中,使用like过滤日期对于日期而言变得有点复杂。 您可以尝试以下代码,这些代码可以通过在where子句中使用input语句为您工作

 data have;
 input id datecolumn $10.;
  datalines;
  1 20/10/2018
  1 25/10/2018
  2 30/10/2018
  2 01/11/2018
  ;

 proc sql;
 create table want as 
  select *  from have
 where input(datecolumn, ddmmyy10.) between '20Oct2018'd and '30Oct2018'd ;

使用如下所示的上述相同代码

proc sql;
create table want as 
 select *  from have
 /*include all dates which start with 2 */
 where datecolumn like '2%' and  datecolumn like '%10/2018' 
 or datecolumn = '30/10/2018';

EDIT1:

看起来您遇到了数据质量问题,示例数据集如下所示。 尝试这个。 我想再说一遍,将日期存储为字符值的方法不好,将来可能导致很多问题。

   data have;
  input id datecolumn $10.;
  datalines;
   1 20/10/2018
   1 25/10/2018
   2 30/10/2018
   2 01/11/2018
   3 01/99/2018
   ;

   proc sql;
  create table want(drop=newdate) as 
  select *,  case  when input(datecolumn, ddmmyy10.) ne .
                  then input(datecolumn, ddmmyy10.)
                    else . end as newdate from have
where calculated newdate between '20Oct2018'd and '30Oct2018'd 

;

或者,您可以放置​​您的case语句而无需添加和删除新列,如下所示。

    proc sql;
    create table want as 
    select * from have
     where 
    case  when input(datecolumn, ddmmyy10.) ne .
    then input(datecolumn, ddmmyy10.) between '20Oct2018'd and '30Oct2018'd 
    end;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM