【问题标题】:get latest column value from hive table conditionally on other columns有条件地在其他列上从配置单元表中获取最新列值
【发布时间】:2018-05-17 07:58:58
【问题描述】:

我有一个 Hive 表“订单”,其中包含四列(id 字符串、名称字符串、订单字符串、ts 字符串)。表格样本数据如下。

-------------------------------------------
id  name    order               ts
------------------------------------------- 
1   abc     completed       2018-04-12 08:15:26     
2   def     received        2018-04-15 06:20:17
3   ghi     processed       2018-04-16 11:36:56
4   jkl     received        2018-04-05 12:23:34
3   ghi     received        2018-03-23 16:43:46
1   abc     processed       2018-03-17 18:39:22
1   abc     received        2018-02-25 20:07:56

订单列具有三种状态:已收到 -> 已处理 -> 已完成。一个名称有许多订单,每个订单都有这三个阶段。我需要给定“id”和“name”的最新订单值。这对您来说似乎是一个新手问题,但我对此感到困惑。

我尝试编写如下查询,但它们不起作用,我无法直接在“ts”列上使用 max 函数,因为它是字符串格式。请教一个最好的方法。 提前致谢。

我尝试过的查询

SELECT
ORDER
FROM Orders
WHERE id = '1'
    AND name = 'ghi'
    AND ts = (
        SELECT max(unix_timestamp(ts, 'yyyy-MM-dd HH:mm:SS'))
        FROM Orders
        )

编译语句时出错:FAILED: ParseException line 2:0 cannot identify input near 'select' 'max' '(' in expression specification

SELECT
ORDER
FROM Orders
WHERE id = '1'
    AND name = 'ghi'
    AND max(unix_timestamp(ts, 'yyyy-MM-dd HH:mm:SS'))

编译语句时出错:FAILED: SemanticException [Error 10128]: Line 1:93 Not yet supported place for UDAF 'max'

select o.order  from Orders o
inner join ( 
    select id, name, order, max(ts) as ts
    from Orders
    group by id, name, order
) ord on d.id = ord.id and o.name = ord.name and o.ts = ord.ts where o.id = '1' and o.name = 'abc'

此查询已执行,但输出不是单个最新订单阶段,而是每个订单阶段都有相应的最新时间戳。

请帮忙。

【问题讨论】:

    标签: sql hive impala


    【解决方案1】:

    对于给定的订单,您需要一行。因此,您可以使用order bylimit

    SELECT o.*
    FROM Orders o
    WHERE id = 1 AND  -- presumably id is a number
         name = 'ghi'
    ORDER BY ts DESC
    LIMIT 1;
    

    这也应该有最好的性能。

    【讨论】:

    • 感谢您的回答。我将尝试上述查询并返回。所有列都是字符串类型。
    • 我只想要订单列的值。你的查询给了我整行。你能告诉任何其他方法找到它吗
    • @RSG 。 . .如果您只想要一列,请选择该列而不是 *
    【解决方案2】:

    您可以使用 RANK 分析功能来解决您的问题,如下所示:

    select id,name,order,ts
    from (select id,name,order,ts,rank() over(partition by id,name order by ts) r from orders)k
    where r = 1
    and id = '1'
    and name = 'ghi'
    

    如果您想获取所有 ID 和名称的最新记录,则无需传递“ID”和“NAME”的值,您将轻松获得所需的结果。

    一切顺利!!!

    【讨论】:

    • 感谢您的回答。我需要特定 id 和名称的记录,有什么方法可以使用上述查询并获得所需的输出
    • 我发布的遗嘱将返回特定 ID 的行,仅带有最新时间戳的NAME,它不返回吗?
    猜你喜欢
    • 2021-01-04
    • 1970-01-01
    • 1970-01-01
    • 2018-08-08
    • 1970-01-01
    • 2017-01-08
    • 2020-04-27
    • 2017-07-02
    • 2017-10-11
    相关资源
    最近更新 更多