【发布时间】:2014-04-23 18:42:39
【问题描述】:
我有一个非常大的表,其中包含一个 ID 字段和一个日期时间字段。该表按 ID 字段排序,并在日期时间字段上进行索引。
我想快速找到最大日期时间值,但找不到任何好方法。
样本数据:
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:PROC SQL 与 inobs 或 outobs
@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;
帮助!
【问题讨论】:
-
这个日期时间字段的连续性如何?您基本上有单独的索引记录,还是日期时间真的存储了更大的东西并且每个相同的日期时间值有很多记录?
-
对于给定的日期时间,可能有多个记录 - 甚至可以达到毫秒。
-
有可能,但正常吗?
-
是的,它经常发生。我通常不会查看毫秒值,因为在将数据导入 SAS 时我会截断它们。对于我们如何使用数据,我们不需要那种粒度级别。
-
嗯,我想。我通常会有一个不同的表,只存储 datetime 和 eventID 或类似的东西,这样会更容易。