即使在找到真实条件后,也会评估 Case When 和 Else 语句



使用 SAS,我创建了一个名为 Flag 的全局宏变量,该变量为 0 或 1,具体取决于代码采用的路径。 如果为 0,则仅创建表 A。 如果为 2,则创建 A 和 B。 然后,我想创建一个汇总表。 如果只有 A 存在,我需要 A 中某个变量的最大值。 如果 B 存在,我需要 B 中同一变量的最大值,而不是 A。 我的 SQL 代码如下所示:

Proc SQL; create table WANT as 
case
when &flag. = 0 then (select max(var) from A)
when &flag. = 1 then (select max(var) from B)
end as Var2
from HAVE;

问题是当 Flag = 0 时,我收到一条错误消息,指出"表 B 不存在"(这是正确的,表 B 将不存在)。 我在网上找到许多消息来源说,在找到第一个真实条件后,它应该退出。 考虑到可能出于某种原因它正在评估所有 when 子句,我尝试将其更改为如下所示:

Proc SQL; Create table WANT as select
case
when &flag. = 0 then (select max(var) from A)
else (select max(var) from B)
end as Var2;

在上面的代码中,它甚至不应该进入 else 语句。 我知道一个事实,变量和比较都正确解析,因为我分别尝试了它们中的每一个,并且当 flag = 1 时它也可以正常工作。 我可以使用任意数量的解决方法,例如虚拟表、全局 %if-%then 等。 我希望能够解决代码中的问题,但也想知道我是否了解SQL如何处理他们的CASE-WHEN语句。

在代码开始运行后修改代码为时已晚。

假设宏变量 FLAG 具有实际值(而不是要引用的某个变量的名称),则可以使用宏逻辑有条件地生成代码。

proc sql ; 
create table WANT as 
%if  &flag. = 0 %then %do;
select max(var) from A
%end;
%else %do;
select max(var) from B
%end;
;
quit;

如果将过程更改为将源数据集的名称放入宏变量中,而不是将值 0 或 1 设置为宏变量,则可能会更容易。 然后,只需使用该宏变量代替查询中的数据集名称。

%let sourceds=A;
proc sql ; 
create table WANT as select max(var) from &sourceds;
quit;

SAS 是正确的。 您将计算表达式与解析SQL 语句混淆了。

在分析阶段,所有表和列都需要存在。 这与实际计算表达式不同。

我不太熟悉在SASproc sql或任何数据库中做你想做的事的方法。