我有一个非常大的表,其中包含ID字段和日期时间字段.该表按ID字段排序,并在日期时间字段中按INDEXED排序. 我想快速找到最大日期时间值,但我找不到任何好的方法来做到这一点. 样本数据
我想快速找到最大日期时间值,但我找不到任何好的方法来做到这一点.
样本数据:
data x; do id=1 to 10000000; created_datetime = datetime() + (ranuni(1)*100000); output; end; format created_datetime datetime22.; run; proc sql noprint; create index created_datetime on x; quit;
尝试#1:PROC SQL和max()函数
出于某种原因,我认为这会立即返回结果,但我发现实际发生的事情是反直觉的(至少对我而言).使用max()函数不使用索引 – 它不能! where子句等可以使用索引,但max()函数不能.即使您强制使用索引,它仍然会处理表中的所有行,只是按照使用索引返回它们的顺序.
option msglevel=i; proc sql noprint; select max(created_datetime) from x(idxname=x); quit;
尝试#2:按组处理
下面使用索引轻松返回第一行:
data min; set x; by created_datetime; output; stop; run;
但我不能使用descending关键字在列表中向后工作以获取最后一行:
data min; set x; by descending created_datetime; output; stop; run;
SAS似乎也不支持降序索引,所以我也不能使用这种方法.
尝试#3:使用有关索引和WHERE语句的元数据
我查看了SASHELP.VINDEX,希望可能最大值可能存储在我可以在where语句中使用的元数据中.那里没有运气.
编辑:
尝试#4:使用inobs或outobs的PROC SQL
@ DomPazz下面的回答激发了我重新审视其他一些基于SQL的解决方案.我想也许PROC SQL中的order by语句可能会与inobs或outobs选项进行交互以实现我的目标.虽然它没有用.排序看起来像应用于查询的输出,并且决不会影响实际读入行的顺序.
/* Uncomment options as necessary */ proc sql noprint /*inobs=1 outobs=1*/; create table temp as select created_datetime from x order by created_datetime desc; quit;
救命!
这为你提供了百分位 – 最后一个应该是100%的标记.这要求在对数据进行任何添加/删除之后使用UPDATECENTILES选项重新创建索引.proc contents data=have centiles; run;
如果您希望将其作为数据集(输出表名称为“INDEXES”),则可以使用ODS OUTPUT获取该值:
ods output indexes=temp; proc contents data=have centiles ; run;
有关详细信息,请参阅Michael Raithel的论文,特别是The Basics Of Using SAS Indexes.