概述
最近在写一些需求,用到了impala中的窗口函数,在这里记录下常用的窗口函数。后续也会把这些sql通过spark sql集成执行spark任务,去定时调度。
后面我会首先介绍一些窗口函数,然后再结合具体的应用进行进一步理解。
常用窗口函数
1. UUID()
作用:返回 通用唯一标识符,128位值,编码为字符串,其中十六进制数字组由短划线分隔。
返回类型: STRING
版本需求: Impala 2.5.0
使用说明:
类型的升序数字序列BIGINT通常用作表中的标识符,并用作跨多个表的连接键。该 UUID()值是一种方便的替代方法,不需要存储或查询最高序列号。例如,您可以使用它在数据导入作业期间快速构建新的唯一标识符,或者组合来自不同表的数据而不会发生ID冲突。
- demo
select uuid();
+--------------------------------------+
| uuid() |
+--------------------------------------+
| c7013e25-1455-457f-bf74-a2046e58caea |
+--------------------------------------+
2. CONCAT(STRING a,STRING b …)
作用:返回表示连接在一起的所有参数值的单个字符串。
返回类型: STRING
使用说明:想要多个字段进行拼接时就可以使用CONCAT,来取代UUID。如果有任务重跑时,想覆盖以前的数据,就可以使用CONCAT拼接某些字段,使得这些字段无论第一次跑还是第二次都是一样的,这样就可以达到覆盖的作用。
- demo
SELECT concat('aa','bbb','ccc');
+--------------------------------------+
| concat('aa','bbb','ccc') |
+--------------------------------------+
| aabbcc |
+--------------------------------------+
3. CONCAT_WS(STRING sep,STRING a,STRING b …)
作用:返回表示连接在一起的第二个和后续参数值的单个字符串,由指定的分隔符分隔。
返回类型: STRING
使用说明: concat_ws()可以指定分隔符,例如:下划线,中划线,竖线等。
- demo
4. CAST(expr AS类型)
作用:将表达式的值转换为任何其他类型。如果表达式值是无法转换为目标类型的类型,则结果为NULL。
返回类型: 用户自己指定的类型
使用说明:使用CAST通过列值或文字给需要与不同类型的参数的函数时。经常在SQL操作中使用,例如CREATE TABLE AS SELECT,INSERT … VALUES等语句,确保来自各种源的值是目标列的适当类型。在可行的情况下,CAST()执行一次操作以使每列成为适当的类型,而不是CAST()在每个查询中使用许多操作; 在每个查询期间为每行执行类型转换对于具有数百万或数十亿行的表来说可能是昂贵的。
- demo
SELECT CONCAT('Here are the first ',CAST(10 AS STRING),' results.');
CREATE TABLE t1 (name STRING, x STRING, y STRING, z STRING);
CREATE TABLE t2 STORED AS PARQUET
AS SELECT
name,
CAST(x AS BIGINT) x,
CAST(y AS TIMESTAMP) y,
CAST(z AS SMALLINT) z
FROM t1;
注意:
DECIMAL数据类型(Impala 3.0或仅限更高), CHAR数据类型(仅限Impala 2.0或更高版本), VARCHAR数据类型(仅限Impala 2.0或更高版本)。可以参考官网去查看。
5 .FLOOR(DOUBLE a), FLOOR(DECIMAL(p,s) a), DFLOOR(DOUBLE a), DFLOOR(DECIMAL(p,s) a)
作用:返回小于或等于参数的最大整数。
返回类型:与输入类型相同
- demo
select floor(1.9);
+--------------------------------------+
| floor(1.9) |
+--------------------------------------+
| 1 |
+--------------------------------------+
6. TO_DATE(TIMESTAMP ts)
作用:吧时间戳值返回日期字段的字符串表示形式。
返回类型: STRING
- demo
select now() as right_now,
concat('The date today is ',to_date(now()),'.') as date_announcement;
+-------------------------------+-------------------------------+
| right_now | date_announcement |
+-------------------------------+-------------------------------+
| 2016-06-01 16:30:36.890325000 | The date today is 2016-06-01. |
+-------------------------------+-------------------------------+
7. TO_TIMESTAMP(BIGINT unixtime),TO_TIMESTAMP(STRING date,STRING pattern)
作用:将表示日期/时间值的整数或字符串转换为相应的TIMESTAMP值。
返回类型: TIMESTAMP
版本需求: Impala 2.3.0
使用说明:
传入一个BIGINT时代表把unix的时间转化为timestamp
字符串参数加上另一个表示模式的字符串参数,将日期和时间的任意字符串表示形式转换为真 TIMESTAMP值。解析多种日期和时间格式的功能允许您处理来自不同来源的时态数据,并在需要TIMESTAMP时在ETL过程中转换为有效值。通过TIMESTAMP直接在查询和表达式中使用,您可以在每次引用适用的列时执行日期和时间计算,而无需额外函数调用和转换的开销。
- demo
- 如何将任意字符串表示形式转换为TIMESTAMP基于模式字符串:
select to_timestamp('Sep 25, 1984', 'MMM dd, yyyy');
+----------------------------------------------+
| to_timestamp('sep 25, 1984', 'mmm dd, yyyy') |
+----------------------------------------------+
| 1984-09-25 00:00:00 |
+----------------------------------------------+
select to_timestamp('1984/09/25', 'yyyy/MM/dd');
+------------------------------------------+
| to_timestamp('1984/09/25', 'yyyy/mm/dd') |
+------------------------------------------+
| 1984-09-25 00:00:00 |
+------------------------------------------+
- 将BIGINT表示秒数转换为TIMESTAMP值
-- One day past the epoch.
select to_timestamp(24 * 60 * 60);
+----------------------------+
| to_timestamp(24 * 60 * 60) |
+----------------------------+
| 1970-01-02 00:00:00 |
+----------------------------+
-- 60 seconds in the past.
select now() as 'current date/time',
unix_timestamp(now()) 'now in seconds',
to_timestamp(unix_timestamp(now()) - 60) as '60 seconds ago';
+-------------------------------+----------------+---------------------+
| current date/time | now in seconds | 60 seconds ago |
+-------------------------------+----------------+---------------------+
| 2017-10-01 22:03:46.885624000 | 1506895426 | 2017-10-01 22:02:46 |
+-------------------------------+----------------+---------------------+
8. FROM_UNIXTIME(BIGINT unixtime [,STRING格式])
作用:将Unix纪元到指定时间的秒数转换为本地时区的字符串。
返回类型: STRING
注意: 目前,格式字符串区分大小写,尤其是区分 m分钟和M月份。在Impala 1.3及更高版本中,您可以切换元素的顺序,使用替代分隔符,并为每个单元使用不同数量的占位符。加入更多的实例 y,d,H,等等产生输出串零填充字符的请求数量。例外是 M几个月,其中M产生非填充值,例如3,MM产生零填充值,例如 03,MMM产生缩写的月份名称,例如 Mar,以及4个或更多的序列M不允许。日期字符串包括所有字段可以是’yyyy-MM-dd HH:mm:ss.SSSSSS’,‘dd/MM/yyyy HH:mm:ss.SSSSSS’, 'MMM dd, yyyy HH.mm.ss (SSSSSS)'或占位符和分隔符的其它组合。
- demo
SELECT FROM_UNIXTIME(1392394861,'yyyy-MM-dd HH:mm:ss.SSSS');
+-------------------------------------------------------+
| from_unixtime(1392394861, 'yyyy-mm-dd hh:mm:ss.ssss') |
+-------------------------------------------------------+
| 2014-02-14 16:21:01.0000 |
+-------------------------------------------------------+
SELECT FROM_UNIXTIME(1392394861,'HH:mm:ss.SSSS');
+--------------------------------------------+
| from_unixtime(1392394861, 'hh:mm:ss.ssss') |
+--------------------------------------------+
| 16:21:01.0000 |
+--------------------------------------------+
9. UNIX_TIMESTAMP(),UNIX_TIMESTAMP(STRING datetime),UNIX_TIMESTAMP(STRING datetime,STRING格式),UNIX_TIMESTAMP(TIMESTAMP datetime)
作用:返回Unix时间,这是自“1970-01-01 00:00:00”UTC以来经过的秒数。如果不带参数调用,则将当前日期和时间转换为Unix时间。如果使用参数调用,则第一个参数表示为TIMESTAMP或STRING转换为其Unix时间。
返回类型: BIGINT
- demo
- UNIX_TIMESTAMP()并且FROM_UNIXTIME() 经常组合使用以将TIMESTAMP 值转换为特定的字符串格式。例如:
SELECT FROM_UNIXTIME(UNIX_TIMESTAMP(NOW() + interval 3 days),
'yyyy/MM/dd HH:mm') AS yyyy_mm_dd_hh_mm;
+------------------+
| yyyy_mm_dd_hh_mm |
+------------------+
| 2016/06/03 11:38 |
+------------------+
- 以下示例显示了将相同日期和时间转换为整数值的不同方法。Impala默认识别的格式字符串被解释为UTC日期和时间。尾随Z是对时区为UTC的确认。如果日期和时间字符串的格式不同,则第二个参数指定每个日期和时间值的位置和单位。
-- 3 ways of expressing the same date/time in UTC and converting to an integer.
select unix_timestamp('2015-05-15 12:00:00');
+---------------------------------------+
| unix_timestamp('2015-05-15 12:00:00') |
+---------------------------------------+
| 1431691200 |
+---------------------------------------+
select unix_timestamp('2015-05-15 12:00:00Z');
+----------------------------------------+
| unix_timestamp('2015-05-15 12:00:00z') |
+----------------------------------------+
| 1431691200 |
+----------------------------------------+
select unix_timestamp
(
'May 15, 2015 12:00:00',
'MMM dd, yyyy HH:mm:ss'
) as may_15_month_day_year;
+-----------------------+
| may_15_month_day_year |
+-----------------------+
| 1431691200 |
+-----------------------+
-- The resulting integer is different from the previous examples.
select unix_timestamp
(
'2015-05-15 12:00:00-07:00',
'yyyy-MM-dd HH:mm:ss-hh:mm'
) as may_15_year_month_day;
+-----------------------+
| may_15_year_month_day |
+-----------------------+
| 1431716400 |
+-----------------------+
10. FROM_TIMESTAMP(TIMESTAMP datetime, STRING pattern), FROM_TIMESTAMP(STRING datetime, STRING pattern)
作用:将TIMESTAMP值转换为表示相同值的字符串。
返回类型: STRING
版本: Impala 2.3.0
使用说明:
该FROM_TIMESTAMP()函数提供了一种灵活的方法,可将TIMESTAMP值转换 为任意字符串格式以进行报告。
因为Impala隐式地将字符串值转换为TIMESTAMP,所以您可以将表示为字符串的日期/时间值(以标准 yyyy-MM-dd HH:mm:ss.SSS格式)传递给此函数。结果是使用不同分隔符字符,字段顺序,拼写月份名称或日期/时间字符串表示的其他变体的字符串。
- demo
-- Reformat a TIMESTAMP value.
SELECT FROM_TIMESTAMP(NOW(), 'yyyy/MM/dd');
+-------------------------------------+
| from_timestamp(now(), 'yyyy/mm/dd') |
+-------------------------------------+
| 2018/10/09 |
+-------------------------------------+
-- Alternative format for reporting purposes.
SELECT FROM_TIMESTAMP('1984-09-25 16:45:30.125', 'MMM dd, yyyy HH:mm:ss.SSS');
+------------------------------------------------------------------------+
| from_timestamp('1984-09-25 16:45:30.125', 'mmm dd, yyyy hh:mm:ss.sss') |
+------------------------------------------------------------------------+
| Sep 25, 1984 16:45:30.125 |
+------------------------------------------------------------------------+
11. LPAD(STRING str, INT len, STRING pad)
作用:根据第一个参数字符串返回指定长度的字符串。如果指定的字符串太短,则会在左侧填充指定字符串。如果指定的字符串太长,则会在右侧截断。
返回类型: STRING
- demo
SELECT lpad('1',2,'0');
+-----------------------+
| lpad('1',2,'0') |
+-----------------------+
| 01 |
+-----------------------+
规定字符串长度为2,长度不够从左边补0
12. HOUR(TIMESTAMP ts)
作用:返回字段中的小时TIMESTAMP字段。
返回类型: INT
- demo
select now() as right_now, hour(now()) as current_hour;
+-------------------------------+--------------+
| right_now | current_hour |
+-------------------------------+--------------+
| 2016-06-01 14:14:12.472846000 | 14 |
+-------------------------------+--------------+
select now() + interval 12 hours as 12_hours_from_now,
hour(now() + interval 12 hours) as hour_in_12_hours;
+-------------------------------+-------------------+
| 12_hours_from_now | hour_in_12_hours |
+-------------------------------+-------------------+
| 2016-06-02 02:15:32.454750000 | 2 |
+-------------------------------+-------------------+
13. MINUTE(TIMESTAMP date)
作用:从TIMESTAMP值返回分钟字段。
返回类型: INT
- demo
select now() as right_now, minute(now()) as current_minute;
+-------------------------------+----------------+
| right_now | current_minute |
+-------------------------------+----------------+
| 2016-06-01 14:34:08.051702000 | 34 |
+-------------------------------+----------------+
注意:
最后提醒大家impala sql语句作者是通过hue进行测试的,但是最终会写成spark代码,通过spark sql 进行整合sql语句,这里可能出现一些impala中的窗口函数在spark sql 中不能用,所以大家还是要去官网查找,我就遇到一中情况:
from_timestamp函数在hue中可以使用但是跑在spark中提示未注册的函数,说明在spark中并没有这个函数,大家可以使用date_format这个函数。