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

SAS:PROC SQL:如何在不创建新列的情况下将字符格式(dd/mm/yyyy)读取为日期格式?,sql,sas,Sql,Sas,我有一个字符列,其中日期(dd/mm/yyyy)为字符格式 在应用过滤器(where子句)时,我需要在where语句中将这些字符识别为日期,而不实际更改现有列或创建新列 我怎样才能做到这一点。 任何帮助都将不胜感激 谢谢。在proc sql中,您可以使用类似的: select (case when datecol like '__/__/____' then . . . else . . . end) 这只是一个近似值u是一

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

在应用过滤器(where子句)时,我需要在where语句中将这些字符识别为日期,而不实际更改现有列或创建新列

我怎样才能做到这一点。 任何帮助都将不胜感激


谢谢。

proc sql
中,您可以使用
类似的

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

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

proc SQL
中,您可以使用
类似的

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

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

将日期存储为字符值不是一个好主意,它可能会导致许多与数据准确性相关的问题,您甚至可能不知道您有数据问题已经很久了。假设某人输入了错误的字符日期,而你甚至可能不知道。将日期保持为日期值而不是字符值总是好的

在您的代码中,使用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 ;
对上述相同代码使用如下所示的like

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 
)

或者,您可以在不创建和删除新列的情况下放入案例陈述,如下所示

    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;

将日期存储为字符值不是一个好主意,它可能会导致许多与数据准确性相关的问题,并且您可能甚至不知道您已经有了很长一段时间的数据问题。假设某人输入了错误的字符日期,而你甚至可能不知道。将日期保持为日期值而不是字符值总是好的

在您的代码中,使用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 ;
对上述相同代码使用如下所示的like

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 
)

或者,您可以在不创建和删除新列的情况下放入案例陈述,如下所示

    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;

带有
信息修饰符的SAS
输入
函数将把字符串(源值)转换为结果,如果源值与信息不一致,则不会显示错误

INPUT
可用于
WHERE
语句或子句中。输入也可以是
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;

带有
信息修饰符的SAS
输入
函数将把字符串(源值)转换为结果,如果源值与信息不一致,则不会显示错误

INPUT
可用于
WHERE
语句或子句中。输入也可以是
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;

如果我必须一次按一个日期筛选,这种方法可能会起作用。但我将如何应用筛选器中的日期范围?@AbhasJangre。你的问题是如何识别被识别为日期的字符串,而不是如何使用值进行比较。如果我必须一次按一个日期进行筛选,这种方法可能有效。但我将如何应用筛选器中的日期范围?@AbhasJangre。您的问题是如何识别被识别为日期的字符串,而不是如何使用值进行比较。在处理where子句时,输入函数报告了“错误:无效的日期值”。您的日期值是什么?您可能会遇到一些与日期不匹配的值。这是我刚才谈到的数据问题。我已经编辑了我的答案,现在您将看到一个错误,但在日志中会看到一个注释:无效的日期值注释:无效的函数输入参数。可能会生成缺少的值。在处理where子句时,输入函数报告了“错误:无效的日期值”。您的日期值是什么,并且可能有一些值与日期不匹配。这是我刚才谈到的数据问题。我已经编辑了我的答案,现在您将看到一个错误,但在日志中会看到一个注释:无效的日期值注释:无效的函数输入参数。可能会生成缺少的值。将来,请确保显示您迄今为止尝试过的内容。将来,请确保显示您迄今为止尝试过的内容。