Impala 中 FIRST() 和 LAST() 的等价物

Posted

技术标签:

【中文标题】Impala 中 FIRST() 和 LAST() 的等价物【英文标题】:Equivalent of FIRST() and LAST() in Impala 【发布时间】:2021-02-04 13:30:19 【问题描述】:

我来自不同传感器单元的数据与 Hadoop 中的 unix_time stam 一起出现。使用 FIRST 和 LAST 语句在 SQL 中获取每天的第一个和最后一个值非常容易,如下所示。在这里,我得到了一天开​​始和结束时的温度。

SELECT unit, FIRST(Temp) as Start_Day_Value, LAST(Temp) as End_Day_Value
FROM Sensor_Data.Table
WHERE cast(ts/1000 as TIMESTAMP) BETWEEN "2021-01-05 00:00:00" AND "2021-01-05 23:59:59"
GROUP BY unit
ORDER BY unit;

在 IMPALA 中是否有任何等效命令,以便我可以像在 SQL 中一样获取每列的第一个和最后一个值。

【问题讨论】:

鉴于 mysql 不支持 FIRST()/LAST(),我对这段代码的来源感到困惑。 【参考方案1】:

标准 SQL 有一个 FIRST_VALUE() window 函数,但不是聚合的等效函数。因此,在 Impala 或几乎任何其他数据库中做你想做的事情的一种方法是:

SELECT DISTINCT unit,
       FIRST_VALUE(Temp) OVER (PARTITION BY unit ORDER BY ts) as Start_Day_Value, 
       FIRST_VALUE(Temp) OVER (PARTITION BY unit ORDER BY ts DESC) as End_Day_Value
FROM Sensor_Data.Table
WHERE cast(ts/1000 as TIMESTAMP) >= '2021-01-05' AND 
      cast(ts/1000 as TIMESTAMP) < '2021-01-06'
ORDER BY unit;

请注意,我还简化了日期比较。

注意:我不确定cast() 是否有效(我希望代码使用from_timestamp())。但这不是你要问的。

编辑:

在 Impala 中,您可以使用 GROUP BY:

SELECT u.unit,
       MAX(CASE WHEN seqnum_asc = 1 THEN temp END) as first_temp,
       MAX(CASE WHEN seqnum_asc = 1 THEN temp END) as lasst_temp
FROM (SELECT unit,
             ROW_NUMBER() OVER (PARTITION BY unit ORDER BY ts) as seqnum_asc, 
             ROW_NUMBER() OVER (PARTITION BY unit ORDER BY ts desc) as seqnum_desc _Day_Value
      FROM Sensor_Data.Table
      WHERE cast(ts/1000 as TIMESTAMP) >= '2021-01-05' AND 
            cast(ts/1000 as TIMESTAMP) < '2021-01-06'
     ) u
GROUP BY unit
ORDER BY unit;

【讨论】:

当我尝试使用 abve 代码时,出现以下错误:AnalysisException: cannot combine SELECT DISTINCT with analytic functions 它不允许我在 SELECT 中添加 DISTINCT陈述。知道如何解决这个问题吗? @ZeeshanShareef 。 . .哇。我从未见过有这种限制的数据库。子查询应该修复它。如果不是,则可以使用聚合替代方法。 在 Impala 中,您不能将 DISTINCT 与分析函数一起使用是很常见的。 @GordonLinoff 您的子查询问题仍未解决。您能推荐任何其他解决方案吗? @ZeeshanShareef 。 . .我添加了我会通常使用的解决方案。我只是推荐使用FIRST_VALUE(),因为它最接近您的原始查询。【参考方案2】:

我通过以下方式解决了这个问题:

SELECT DISTINCT u.unit, u.initial_temp, u.final_temp, u.initial_p, u.final_p
FROM(SELECT unit,
first_value(temperature) OVER(PARTITION BY unit ORDER BY ts DESC) as final_temp,
first_value(temperature) OVER(PARTITION BY unit ORDER BY ts ASC) as initial_temp,
first_value(pressure) OVER(PARTITION BY unit ORDER BY ts DESC) as final_p,
first_value(pressure) OVER(PARTITION BY unit ORDER BY ts ASC) as initial_p
FROM Sensor_Data.Table
WHERE cast(ts/1000 as TIMESTAMP) BETWEEN "2020-12-11 00:00:00" AND "2020-12-11 23:59:59"
) AS u
ORDER BY unit;

【讨论】:

以上是关于Impala 中 FIRST() 和 LAST() 的等价物的主要内容,如果未能解决你的问题,请参考以下文章

first集和last集以firstVT和lastVT的求法

UPDATE 语句中的集合 COUNT、FIRST 和 LAST

在 Django 用户模型中需要 first_name 和 last_name

sas (first、last)

在 Pandas 中使用 group by 时如何将“first”和“last”函数应用于列?

first-child和last-child选择器