按 SAS 中的组与 SQL 中的 window 函数

By Groups in SAS vs window functions in SQL

我有一个 table、input_table,其中包含以下列:

key - double
code - string
date- string
result -string

我有以下 SAS 代码:

PROC SQL;
    CREATE TABLE t1 AS
    SELECT key, code, date, result
    from input_table
    ORDER BY key, code, date;
QUIT;


DATA t1;
   SET t1;
   final_result= INPUT(result, 5.)
RUN;


DATA t2;
   SET t1;
   WHERE NOT MISSING(final_result)
   BY key, code, date

   IF LAST.code;
RUN;

所以根据我的理解,这段代码是添加列'final_result',这是转换为数值的结果,如果包含非数值则为NULL。然后它选择具有每个键、代码对的最大日期的行。我试图在 hiveQL 中复制它(我认为对于这种情况,它与 SQL 几乎相同):

select key, code, date, result, final_result 
from
(select *, 
 row_number() over (partition by key, code order by date desc) as rnk, 
 cast(result as double) as final_result
 from input_table
) x
where rnk=1 and final_result is not null

这个查询是否等同于上面的 SAS 代码? (我会测试自己,但目前遇到环境问题)

我看到的唯一主要问题是最后一行的最终结果可能是 null/missing。

在 SAS 中,where 子句发生在数据步骤处理之前,因此它实际上等同于将它放在 partition 语句中(我不确定这是否可能)and/or 在前面的步骤中。如果按日期排序的最后一行恰好为空,SAS 将跳过它并取最后一行 not 为空(因为它不会在数据流中开始).

在你的 SQL 中,如果 rank=1 碰巧有 final_result is null,它将被删除 - 但 rank=2 或任何行都不会保留(所以你在您的输出中没有 任何 行对应于该特定 key/code 组合。

select key, code, date, result, final_result 
from
(select s.*, 
 row_number() over (partition by key, code order by date desc) as rnk
 from (
   select *, cast(result as double) as final_Result
   from input_table 
   where final_Result is not null
   ) s
) x
where rnk=1

类似的东西应该是等​​价的。

我能看到的唯一其他潜在问题:如果您有两行日期完全相同,SAS 将选择输入数据集顺序中的 "last" 行。我不知道 Hive 会做什么;但是,在大多数 SQL 实现中,您应该假设您会随机获得一个,因为 SQL 不会尝试保留行顺序。