SAS Proc SQL执行EXCEPT后日期与开盘价列为空的问题求助
解决SAS Proc SQL中EXCEPT语句导致日期列和开盘列空值的问题
问题场景
以下是用户的SAS数据准备代码:
data BTC1; input date mmddyy10. open close; cards; 12/28/2021 50679.85 47588.85 12/29/2021 47623.87 46444.71 12/30/2021 46490.60 47178.12 12/31/2021 47169.37 46306.44 1/1/2022 46311.74 47686.81 1/2/2022 47680.92 47345.21 1/3/2022 47343.54 46458.11 1/4/2022 46458.85 45897.57 ; data BTC2; input date mmddyy10. open close; cards; 12/31/2021 47169.37 46306.44 1/1/2022 46311.74 47686.81 1/2/2022 47680.92 47345.21 1/3/2022 47343.54 46458.11 1/4/2022 46458.85 45897.57 1/5/2022 45899.35 43569.00 1/6/2022 43565.51 43160.92 1/7/2022 43153.57 41557.90 ;
执行以下Proc SQL语句后,输出结果的date列和open列全部为空,仅close列有数据:
proc sql; select BTC1.date , open, close from BTC1 except Select * from BTC2; quit;
用户尝试过论坛上删除列的方案,但无法解决问题,现寻求有效解决办法。
问题根源
SAS的EXCEPT语句对两个查询的输出结果有严格要求:列的数据类型、顺序、长度必须完全匹配。当前代码中,第一个查询显式指定列,第二个查询用Select *,虽然列顺序一致,但存在两个核心问题:
- 日期列在SAS中是数值型(存储为自1960年以来的天数),依赖
mmddyy10.格式显示,EXCEPT操作后会丢失格式信息,导致显示为空; - 隐式的列匹配可能触发SAS的类型转换逻辑,导致
open列的值无法正常返回。
有效解决方案
方案1:统一显式指定列与格式
修改EXCEPT两侧的查询,均显式指定列,并为日期列保留显示格式,确保输出结构完全匹配:
proc sql; select date format=mmddyy10., open, close from BTC1 except select date format=mmddyy10., open, close from BTC2; quit;
方案2:用LEFT JOIN替代EXCEPT实现差异查询
如果EXCEPT的严格匹配仍有问题,可以通过左连接筛选出BTC1中不在BTC2的记录,这种方式更直观且避免格式丢失:
proc sql; select a.date format=mmddyy10., a.open, a.close from BTC1 a left join BTC2 b on a.date = b.date and a.open = b.open and a.close = b.close where b.date is null; quit;
内容的提问来源于stack exchange,提问作者Ryan Andrews
相关产品推荐
相关产品推荐

