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