WHERE 语句冷知识
前几天,我在一篇文章中看到这样的说法:
数据步中的 WHERE 语句可以有三种写法:
①作为输入数据集的 WHERE= 选项;
②作为输出数据集的 WHERE= 选项;
③作为单独的 WHERE 语句;
三者的运行速度的快慢关系为:①最快,②次之,③最慢。
阅读到这里时,我产生了疑问,方式①和方式③都是直接应用于输入数据集,运行速度怎么会不一样呢?我打算进行实验,一探究竟。通过编写SAS程序,我生成了一个包含超过一千万条服从0到1之间均匀分布的随机数据的数据集,然后用三种不同位置的 WHERE 条件筛选出大于0.5的数据。我编写了一个简单的程序,它将3种方式各自运行30遍,然后计算3种方式的运行时间和、均值和中位数,最后,我还将实验过程录制成了视频。

实验结果显示,三者的运行速度应该是:①≈③,②最慢。看来,要获得真正的知识,非得要亲身实践不可。
通过查询软件手册,以及自身多年的工作经验,我还总结了以下关于 WHERE 语句的冷知识:
1. 联合使用 WHERE 语句和 WHERE= 选项
1.1 数据步中,WHERE=选项应用到单独的数据集,WHERE 语句应用到所有未指定WHERE=选项的数据集;
1.2 过程步中,WHERE= 选项和 WHERE 语句指定的表达式会以 and 逻辑进行连接,组合成新的 WHERE 表达式,应用到输入数据集;


2. WHERE 语句的使用限制
2.1 在DATA步中,读取 DATALINES或CARDS语句指定的数据行时,不可以使用 WHERE 语句;
2.2 在DATA步中,读取 INFILE 语句指定的外部数据文件时,不可以使用 WHERE 语句;
2.3 当在 SET 或 MODIFY 语句中指定 POINT= 选项时,不可以使用 WHERE 语句;



3. WHERE 语句的使用便利
3.1 WHERE 语句允许单独使用一个数值型变量作为表达式,此时,数值0或缺失值为假,其它值为真;
3.2 WHERE 语句允许单独使用一个字符型变量作为表达式,此时,缺失值为假,其它值为真;

4. 扩充 WHERE 子句
可以使用 WHERE SAME AND 或 WHERE ALSO 语句对前述 WHERE 语句进行扩充,这在语义上等价于在一个 WHERE 语句中用 and 运算符连接多个表达式,但是在编写和维护方面更具优势。

5. 未记录的功能
在 SAS 中有未记录在软件手册中的函数 monotonic(),它可以返回当前观测的行号。当想通过 WHERE 语句筛选观测行号时,不可以使用自动变量_N_(因为该变量衍生于PDV中,而WHERE语句在PDV之前筛选数据),但却可以使用 monotonic() 函数。

以上几点中,我最常用到的是第3和第4点,也希望这些知识能给正在阅读的你带来帮助。