SAS中的按组与SQL中的窗口函数

SAS中的按组与SQL中的窗口函数,sql,hive,sas,hiveql,window-functions,Sql,Hive,Sas,Hiveql,Window Functions,我有一个表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_re

我有一个表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几乎相同):


此查询是否等同于上述SAS代码?(我会测试自己,但目前存在环境问题)

我看到的唯一主要问题是,最后一行的最终结果可能为空/缺失

在SAS中,
where
子句发生在数据步骤处理之前,因此它实际上相当于在
partition
语句中(我不确定是否可能)和/或在较早的步骤中。如果按日期排序的最后一行恰好为空,SAS将跳过它并获取非空的最后一行(因为它不在数据流中)

但是,在SQL中,如果秩=1碰巧有
final_结果为null
,它将被删除-但是
rank=2
或任何行都不会被保留(因此在输出中不会有任何特定键/代码组合的行)

沿着这些思路的东西应该是等价的


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

是否为
final\u result
null?如果是这样,那么一个问题可能是您在外部查询中将其限制为不为null-因此
rnk=1
最后一行上可能为true\u结果为null
行,这意味着您完全错过了该行。另外,还有一个更好的问题,感谢您对其进行了改进。我建议还添加一些示例数据(输入数据)和您认为输出数据应该是什么样子的示例。如果结果包含任何非数字字符,则最终结果将为null。我相信“何处不缺”(最终结果)“SAS代码中的第行指出,我们只选择最终结果不为null的行,这相当于sql@JoeThanks,这个响应非常有用。然而,关于SQL不保留行顺序的最后一部分,这是否意味着没有办法让hiveql与sas 100%匹配@JoeIt总是可能的,只是可能会有更多的工作。事实上,您是否有两个关键代码行的
日期值相同(精确)的行?另外,根据我对你以前的问题的记忆,这些表首先是从SQL构建的;因此,行顺序可能并不重要。(一个直接的
select
通常会保留行顺序,虽然并不总是在那里;但是分区可以做各种事情,包括二叉树之类的事情,这可能会导致行顺序到处都是。)但是您可以始终在开始时创建一个行顺序变量,如果没有其他事情的话,比如一个
row\u number
或任何配置单元的等价物,然后根据max(这一点)进行选择。我要注意的是,我不知道配置单元的具体情况——只是SQL一般情况——因此值得查找关于该配置单元的特定信息(保留行顺序)。在这方面,Hive似乎有一些特定的选择。
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
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