【问题标题】:Finding lines with extreme values using SQL使用 SQL 查找具有极值的行
【发布时间】:2015-08-10 12:21:33
【问题描述】:

我有一个表 t1,有 4 列:

key, cd, date, result_num

在 SAS 中,我们有以下代码:

PROC SQL;
    create table t2 AS
    select * from t1
    group by key
    having date = MAX(date)
    order by key, cd;
RUN;

我的印象是,在使用聚合函数(例如 MAX)时选择的所有列都必须在 group by 中或应用聚合函数。我的目标是将此 SAS 代码转换为 SQL,有没有办法在 SQL 中执行此操作(更具体地说是 hiveQL)?

【问题讨论】:

  • 这个“SAS 代码”已经是 SQL,因为它在 PROC SQL 中。但是,您确实忘记了 order 子句后的分号。你到底在尝试什么?
  • 抱歉,修正了那个错字。我没有编写此代码,但假设它正在获取每个键的日期最大的行。 @DirkHorsten
  • 关于:*我的印象是,使用聚合函数(例如 MAX)时选择的所有列都必须在 group by 中或应用聚合函数。 *SQL 的 SAS 实现允许选择其他变量并将结果合并回来。这可能是一个非常有用的功能,也可能是不受欢迎的功能,具体取决于用户。

标签: sql group-by hive sas proc-sql


【解决方案1】:

诀窍是访问您的输入表两次:一次用于计算最大日期,一次用于选择适当的数据

如果您查找日期是整个表中出现的最高日期的行,即

PROC SQL;
    create table t2 AS
    select * from t1
    where date = (select MAX(date) from t1)
    order by key, cd;
RUN;

如果您查找日期是同一键的最高日期的行,即

PROC SQL;
    create table t2 AS
    select * from t1 inner join 
    (  select MAX(date) as maxDate 
       from t1  
       group by key) as m1 
       on m1.key = t1.key and m1.maxDate = t1.date
    order by key, cd;
RUN;

【讨论】:

  • 在 OP 的 SAS 代码中,我不确定它是选择日期等于给定键的 max(date) 的所有行,还是只选择一行.按键分组意味着您的结果集将仅包含不同的键,对吗?如果有 2 行 key 和 date 重复,并且 date 也恰好是 max(date),会发生什么? @DirkHorsten
  • 原始 SAS 代码没有删除重复观察的逻辑。因此,如果 MAX(date) 与 KEY 的特定值存在关联,则将选择所有此类观察。
  • 试试select distinct
【解决方案2】:

我认为您的查询在 SAS 中没有做您想做的事情。 . .也许确实如此。在标准 SQL(和 Hive)中,您可以这样做:

create table t2 AS
    select *
    from (select t1.*,
                 row_number() over (partition by key order by date desc) as seqnum
          from t1
         ) t1
    where seqnum = 1
    order by key, cd;

【讨论】:

  • 添加order子句后是否忘记删除分号?
  • 这不会只选择一行吗?而在 OP 中,如果它们都包含 MAX(日期),则可以选择多行? @GordonLinoff
  • @Danzo 。 . .如果您想要重复,请使用rank() 而不是row_number()。通常这种逻辑的目的是每组得到一行,但你的观察是正确的。在大多数数据库中,我希望这比使用子查询的版本更快。
  • 您的查询试图在存在平局时仅返回一个观察结果,这是与原始代码不同的查询。原始代码在 SAS 中工作,但在 SAS 的其他实现中它可能是无效的,因为它选择的变量既不是 GROUP BY 列表或聚合统计信息的一部分。但 SAS 允许这样的查询。
  • @Tom 。 . .我不知道你的意思是什么。如前所述,如果您想要领带,请使用rank()。没有group by,因此您的其余评论无关紧要。
猜你喜欢
  • 1970-01-01
  • 2017-01-13
  • 2019-04-11
  • 1970-01-01
  • 2016-01-27
  • 1970-01-01
  • 2018-12-25
  • 2016-05-21
  • 1970-01-01
相关资源
最近更新 更多