首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >配置单元sql查找最新记录

配置单元sql查找最新记录
EN

Stack Overflow用户
提问于 2012-11-23 12:20:28
回答 8查看 55.9K关注 0票数 29

该表如下:

代码语言:javascript
复制
create table test (
id string,
name string,
age string,
modified string)

像这样的数据:

代码语言:javascript
复制
id    name   age  modifed
1     a      10   2011-11-11 11:11:11
1     a      11   2012-11-11 12:00:00
2     b      20   2012-12-10 10:11:12
2     b      20   2012-12-10 10:11:12
2     b      20   2012-12-12 10:11:12
2     b      20   2012-12-15 10:11:12

我想要获得最新的记录(包括每个列的id,名称,年龄,修改)按id分组,如上面的数据,正确的结果是:

代码语言:javascript
复制
1     a      11   2012-11-11 12:00:00
2     b      20   2012-12-15 10:11:12

我喜欢这样:

代码语言:javascript
复制
insert overwrite table t 
select b.id, b.name, b.age, b.modified 
from (
        select id,max(modified) as modified 
        from test 
        group by id
) a 
left outer join test b on (a.id=b.id  and a.modified=b.modified);

这个sql可以得到正确的结果,但是当有大量数据时,它的运行速度会很慢。

**有没有办法不使用left outer join?**

EN

回答 8

Stack Overflow用户

发布于 2013-11-30 20:57:52

Hive SQL有一个几乎没有文档记录的特性(我是在他们的一个Jira bug报告中找到的),它允许您使用struct()执行argmax()之类的操作。例如,如果您有这样一个表:

代码语言:javascript
复制
test_argmax
id,val,key
1,1,A
1,2,B
1,3,C
1,2,D
2,1,E
2,1,U
2,2,V
2,3,W
2,2,X
2,1,Y

您可以这样做:

代码语言:javascript
复制
select 
  max(struct(val, key, id)).col1 as max_val,
  max(struct(val, key, id)).col2 as max_key,
  max(struct(val, key, id)).col3 as max_id
from test_argmax
group by id

并得到结果:

代码语言:javascript
复制
max_val,max_key,max_id
3,C,1
3,W,2

我认为在val (第一个struct元素)的情况下,它将回到第二列中的比较。我也没有弄清楚是否有一种更简洁的语法可以将单个列从结果结构中提取出来,也许可以使用named_struct?

票数 53
EN

Stack Overflow用户

发布于 2017-04-21 04:01:42

只是与之前的答案略有不同的方法。

下面的示例使用配置单元窗口函数找出最新记录,请阅读更多here

代码语言:javascript
复制
SELECT t.id
    ,t.name
    ,t.age
    ,t.modified
FROM (
    SELECT id
        ,name
        ,age
        ,modified
        ,ROW_NUMBER() OVER (
            PARTITION BY id ORDER BY unix_timestamp(modified,'yyyy-MM-dd hh:mm:ss') DESC
            ) AS ROW_NUMBER   
    FROM test
    ) t
WHERE t.ROW_NUMBER <= 1;

修改后的结果是字符串,因此使用unix_timestamp(modified,'yyyy-MM-dd hh:mm:ss')将其转换为时间戳,然后在时间戳上应用order by。

票数 11
EN

Stack Overflow用户

发布于 2015-05-09 23:24:25

Hive SQL有一个相对较新的特性,即analytic functions and the over clause。这应该可以在没有连接的情况下完成工作

代码语言:javascript
复制
select id, name, age, last_modified 
from ( select id, name, age, modified, 
              max( modified) over (partition by id) as last_modified 
       from test ) as sub
where   modified = last_modified 

这里发生的事情是,子查询生成一个带有额外列last_modified的新行,该列具有对应人员id的最新修改时间戳。(类似于group by所做的事情)这里的关键是,子查询再次让您在原始表中每行一行,然后从中进行过滤。

即使是更简单的解决方案也有可能奏效:

代码语言:javascript
复制
select  id, name, age,  
        max( modified) over (partition by id) last_modified 
from test 
where   modified = last_modified 

顺便说一句,同样的代码也可以在Impala中运行。

票数 10
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13523049

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档