如何选择存储为变量值的条件表达式以在 Proc SQL case 表达式中使用?

问题描述 投票:0回答:1

我使用以下 case 表达式来验证 var1 的值并将值分配给新变量 var1_val。数据集response_options_scan包含一个名为valid_values的列,其中包含从数据字典文件转置的var1的所有有效值。数据集response_options_select 包含一个名为requirement_status 的列,其中包含值“All Records”、“Required”,或诸如“var2 contains xyz”之类的条件(指示何时需要var1)。我试图选择在第三个条件中使用requirement_status,因为此代码在宏中使用来验证数十个变量,并且requirement_status中的条件不应进行硬编码。然而,当硬编码条件 request_status 与使用 select 语句时,我得到不同的结果。

硬编码有效并给出 var1_val 的正确值。

proc sql noprint;
    create table validate_select_test
    as select *
        ,case when var1 in (select valid_values from response_options_scan where variable="var1") then "var1 valid value"
        when var1="" and (select requirement_status from response_options_select where variable="var1") in ("All Records", "Required") then "var1 invalid value: missing" 
        when var1="" and var2 contains 'XYZ' then "var1 invalid value: missing"
        when var1="" then "var1 valid value: missing"
        else "var1 invalid value"
        end as var1_val format=$100.
    from validate_select;
quit;
var1 var2 var1_val
A var1 有效值
ABC var1 有效值:缺失
ABC:XYZ var1 无效值:缺失

使用 select 语句则不会。需要明确的是,response_options_select 中的requirement_status 值,其中variable="var1" 是“var 2 contains 'XYZ'”。如果 var2 不包含 XYZ,则 var1=missing 的记录的 var1_val 的值为“var1 有效值:缺失”。

proc sql noprint;
    create table validate_select_test
    as select *
        ,case when var1 in (select valid_values from response_options_scan where variable="var1") then "var1 valid value"
        when var1="" and (select requirement_status from response_options_select where variable="var1") in ("All Records", "Required") then "var1 invalid value: missing" 
        when var1="" and (select requirement_status from response_options_select where variable="var1") then "var1 invalid value: missing"
        when var1="" then "var1 valid value: missing"
        else "var1 invalid value"
        end as var1_val format=$100.
    from validate_select;
quit;
var1 var2 var1_val
A var1 有效值
ABC var1 无效值:缺失
ABC:XYZ var1 无效值:缺失
sql sas case
1个回答
0
投票

SQL 无法动态更改正在执行的语句。您将需要使用包含语言片段的控制数据来生成使用它们的源代码。

示例:

data response_options_select ;
  infile datalines length=linelength;
  length variable $32 requirement_status $200;
  input variable& requirement_status& ;
datalines;;;;
var1  expr:var2 contains "XYZ"
var1  expr:var2 contains "pqr"
;;;;

%macro case_gen(control=, var=);

  %local dsid index rc;
  %local variable rq_type requirement_status;
  %let dsid = %sysfunc(open(&control(
                              keep=variable requirement_status 
                              where=(variable="&var" and requirement_status like 'expr:%')
                            )
                      ));
  %put %sysfunc(sysmsg());
  %syscall set(dsid);
  ( 0 /* code gen */
  %do %while (%sysfunc(fetch(&dsid))=0);
    or  /* code gen */ %substr(&requirement_status,6)
  %end;
  ) /* code gen */
  %let dsid = %sysfunc(close(&dsid));

%mend;

data have;
  length var1 var2 $200;
  var1 = '' ; var2 = '' ; output;
  var2 = 'ABC'; output;
  var2 = 'ABC:XYZ' ; output;
run;

proc sql;
  create table want as
  select 
    case 
      when missing(var1) and %case_gen(control=response_options_select, var=var1) then 'Invalid: Matched expression in control'
      else 'yada yada yada'
    end as var1_validation
  from have
  ;
quit;

提交时将提交此代码,其中部分代码是生成的代码。

proc sql;
   create table want as
   select
     case
       when missing(var1) and 
       ( 0 
         or var2 contains "XYZ" 
         or var2 contains "pqr" 
       )
       then 
         'Invalid: Matched an expression in the select control data set'
       else 
         'yada yada yada'
     end as var1_validation
   from have
   ;
© www.soinside.com 2019 - 2024. All rights reserved.