flik SQL 参考

一、支持的数据类型
VARCHAR 可变长度字符串 VARCHAR最大容量为4MB。
BOOLEAN 逻辑值 取值为TRUE、FALSE或UNKNOWN。
TINYINT 微整型,1字节整数。 -128~127
SMALLINT 短整型,2字节整数。 -32768~32767
INT 整型,4字节整数。 -2147483648~2147483647
BIGINT 长整型,8字节整数。 -9223372036854775808~9223372036854775807
FLOAT 4字节浮点型 6位数字精度
DECIMAL 小数类型 示例:123.45是DECIMAL(5,2)的值。
DOUBLE 浮点型,8字节浮点型。 15位十进制精度。
DATE 日期类型 示例:DATE’1969-07-20’
TIME 时间类型 示例:TIME ‘20:17:40’
TIMESTAMP 时间戳,显示日期和时间。 示例:TIMESTAMP ‘1969-07-20 20:17:40’
VARBINARY 二进制数据 byte[]数组。

说明 VARBINARY没有最大容量的限制。
Array 数组 使用[]进行引用
二、语法约束
当前Flink SQL只支持SELECT,FROM,WHERE,UNION,聚合,窗口,流表JOIN以及流流JOIN。
数据不能对Source流做insert into操作。
Sink流不能用来做查询操作。
三、语法定义
INSERT INTO stream_name query;
query:
values
| {
select
| selectWithoutFrom
| query UNION [ ALL ] query
}

orderItem:
expression [ ASC | DESC ]

select:
SELECT
{ * | projectItem [, projectItem ]* }
FROM tableExpression [ JOIN tableExpression ]
[ WHERE booleanExpression ]
[ GROUP BY { groupItem [, groupItem ]* } ]
[ HAVING booleanExpression ]

selectWithoutFrom:
SELECT [ ALL | DISTINCT ]
{ * | projectItem [, projectItem ]* }

projectItem:
expression [ [ AS ] columnAlias ]
| tableAlias . *

tableExpression:
tableReference

tableReference:
tablePrimary
[ [ AS ] alias [ ‘(’ columnAlias [, columnAlias ]* ‘)’ ] ]

tablePrimary:
[ TABLE ] [ [ catalogName . ] schemaName . ] tableName
| LATERAL TABLE ‘(’ functionName ‘(’ expression [, expression ]* ‘)’ ‘)’
| UNNEST ‘(’ expression ‘)’

values:
VALUES expression [, expression ]*

groupItem:
expression
| ‘(’ ‘)’
| ‘(’ expression [, expression ]* ‘)’
| CUBE ‘(’ expression [, expression ]* ‘)’
| ROLLUP ‘(’ expression [, expression ]* ‘)’
| GROUPING SETS ‘(’ groupItem [, groupItem ]* ‘)’

四、Flink SQL 常用算子
SELECT
SELECT 用于从 DataSet/DataStream 中选择数据,用于筛选出某些列。

例:SELECT * FROM Table;// 取出表中的所有列

SELECT name,age FROM Table;// 取出表中 name 和 age 两列
与此同时 SELECT 语句中可以使用函数和别名

例:SELECT word, COUNT(word) FROM table GROUP BY word;

WHERE
WHERE 用于从数据集/流中过滤数据,与 SELECT 一起使用,用于根据某些条件对关系做水平分割,即选择符合条件的记录

例:SELECT name,age FROM Table WHERE name LIKE ‘%小明%’;

   SELECT * FROM Table WHERE age = 20;

WHERE 是从原数据中进行过滤,那么在 WHERE 条件中,Flink SQL 同样支持 =、<、>、<>、>=、<=,以及 AND、OR 等表达式的组合,最终满足过滤条件的数据会被选择出来。并且 WHERE 可以结合 IN、NOT IN 联合使用。

例:SELECT name, age

   FROM Table 

   WHERE name IN (SELECT name FROM Table2)

DISTINCT
DISTINCT 用于从数据集/流中去重根据 SELECT 的结果进行去重
例:SELECT DISTINCT name FROM Table;

对于流式查询,计算查询结果所需的 State 可能会无限增长,用户需要自己控制查询的状态范围,以防止状态过大。

GROUP BY
GROUP BY 是对数据进行分组操作。例如我们需要计算成绩明细表中,每个学生的总分。

例:SELECT name, SUM(score) as TotalScore FROM Table GROUP BY name;

UNION 和 UNION ALL
UNION 用于将两个结果集合并起来,要求两个结果集字段完全一致,包括字段类型、字段顺序。不同于 UNION ALL 的是,UNION 会对结果数据去重
例:SELECT * FROM T1 UNION (ALL) SELECT * FROM T2;
JOIN
JOIN 用于把来自两个表的数据联合起来形成结果表,Flink 支持的 JOIN 类型包括:
JOIN - INNER JOIN
LEFT JOIN - LEFT OUTER JOIN
RIGHT JOIN - RIGHT OUTER JOIN
FULL JOIN - FULL OUTER JOIN
这里的 JOIN 的语义和我们在关系型数据库中使用的 JOIN 语义一致。
例:JOIN(将订单表数据和商品表进行关联)
SELECT * FROM Orders INNER JOIN Product ON Orders.productId = Product.id

LEFT JOIN 与 JOIN 的区别是当右表没有与左边相 JOIN 的数据时候,右边对应的字段补 NULL 输出,
RIGHT JOIN 相当于 LEFT JOIN 左右两个表交互一下位置。
FULL JOIN 相当于 RIGHT JOIN 和 LEFT JOIN 之后进行 UNION ALL 操作。
Group Window
根据窗口数据划分的不同,目前 Apache Flink 有如下 3 种 Bounded Window:

Tumble,滚动窗口,窗口数据有固定的大小,窗口数据无叠加;
Hop,滑动窗口,窗口数据有固定大小,并且有固定的窗口重建频率,窗口数据有叠加;
Session,会话窗口,窗口数据没有固定的大小,根据窗口数据活跃程度划分窗口,窗口数据无叠加。
Group Window定义在GROUP BY里,每个分组只输出一条记录:包括一下几种

分组函数:

TUMBLE(time_attr, interval)

跳跃窗口。

time_attr可以设置processing-time或者event-time。

interval设置窗口周期。

HOP(time_attr, interval, interval)

拓展的跳跃窗口(等价于datastream的滑动窗口),可以分别设置输出触发周期和窗口周期。

SESSION(time_attr, interval)

会话窗口,interval表示多长时间没有记录则关闭窗口。

窗口函数:

TUMBLE_START(time_attr, interval)

返回跳跃窗口开始时间。为UTC时区。

TUMBLE_END(time_attr, interval)

返回跳跃窗口结束时间。为UTC时区。

HOP_START(time_attr, interval, interval)

返回拓展的跳跃窗口开始时间。为UTC时区。

HOP_END(time_attr, interval, interval)

返回拓展的跳跃窗口结束时间。为UTC时区。

SESSION_START(time_attr, interval)

返回会话窗口开始时间。为UTC时区。

SESSION_END(time_attr, interval)

返回会话窗口结束时间。为UTC时区。

Tumble Window
Tumble 滚动窗口有固定大小,窗口数据不重叠,具体语义如下:

Tumble 滚动窗口对应的语法如下:
SELECT
[gk],
[TUMBLE_START(timeCol, size)],
[TUMBLE_END(timeCol, size)],
agg1(col1),

aggn(colN)
FROM Tab1
GROUP BY [gk], TUMBLE(timeCol, size)
其中:

[gk] 决定了是否需要按照字段进行聚合;
TUMBLE_START 代表窗口开始时间;
TUMBLE_END 代表窗口结束时间;
timeCol 是流表中表示时间字段;
size 表示窗口的大小,如 秒、分钟、小时、天。
举个例子,假如我们要计算每个人每天的订单量,按照 user 进行聚合分组:

SELECT user, TUMBLE_START(rowtime, INTERVAL ‘1’ DAY) as wStart, SUM(amount) FROM Orders GROUP BY TUMBLE(rowtime, INTERVAL ‘1’ DAY), user;

Hop Window
Hop 滑动窗口和滚动窗口类似,窗口有固定的 size,与滚动窗口不同的是滑动窗口可以通过 slide 参数控制滑动窗口的新建频率。
因此当 slide 值小于窗口 size 的值的时候多个滑动窗口会重叠,具体语义如下:

Hop 滑动窗口对应语法如下:
SELECT
[gk],
[HOP_START(timeCol, slide, size)] ,
[HOP_END(timeCol, slide, size)],
agg1(col1),

aggN(colN)
FROM Tab1
GROUP BY [gk], HOP(timeCol, slide, size)
每次字段的意思和 Tumble 窗口类似:

[gk] 决定了是否需要按照字段进行聚合;
HOP_START 表示窗口开始时间;
HOP_END 表示窗口结束时间;
timeCol 表示流表中表示时间字段;
slide 表示每次窗口滑动的大小;
size 表示整个窗口的大小,如 秒、分钟、小时、天。
举例说明,我们要每过一小时计算一次过去 24 小时内每个商品的销量:

SELECT product, SUM(amount) FROM Orders GROUP BY HOP(rowtime, INTERVAL ‘1’ HOUR, INTERVAL ‘1’ DAY), product
Session Window
会话时间窗口没有固定的持续时间,但它们的界限由 interval 不活动时间定义,即如果在定义的间隙期间没有出现事件,则会话窗口关闭。

Seeeion 会话窗口对应语法如下:
SELECT
[gk],
SESSION_START(timeCol, gap) AS winStart,
SESSION_END(timeCol, gap) AS winEnd,
agg1(col1),

aggn(colN)
FROM Tab1
GROUP BY [gk], SESSION(timeCol, gap)

[gk] 决定了是否需要按照字段进行聚合;
SESSION_START 表示窗口开始时间;
SESSION_END 表示窗口结束时间;
timeCol 表示流表中表示时间字段;
gap 表示窗口数据非活跃周期的时长。
例如,我们需要计算每个用户访问时间 12 小时内的订单量:

SELECT user, SESSION_START(rowtime, INTERVAL ‘12’ HOUR) AS sStart, SESSION_ROWTIME

TopN 语句
TopN语句用于对实时数据中某个指标的前N个最值的筛选。Flink SQL可以基于OVER窗口操作灵活地完成TopN的功能。

语法:

SELECT * FROM

( SELECT *,

ROW_NUMBER() OVER ([PARTITION BY col1[, col2…]]

ORDER BY col1 [asc|desc][, col2 [asc|desc]…]) AS rownum

FROM table_name)

WHERE rownum <= N [AND conditions]

说明

ROW_NUMBER():行号计算函数OVER的窗口,行号计算从1开始。
PARTITION BY col1[, col2…] :指定分区的列,可以不指定。
ORDER BY col1 [asc|desc][, col2 [asc|desc]…]:指定排序的列和每列的排序方向。
如上语法所示,TopN需要两层Query:

查询中使用 ROW_NUMBER()窗口函数来对数据根据排序列进行排序并标上排名。
外层查询中对排名进行过滤,只取前N条。例如N=10即为取前10条的数据。
WHERE条件的限制

为了使Flink SQL能识别出这是一个TopN的query,外层循环中必须要指定 rownum <= N的格式来指定前N条记录。

此时,您不可以将rownum置于某个表达式中,例如rownum - 5 <= N 。WHERE条件中,可以额外带上其他条件,但是必须使用AND连接条件。

GROUPING SETS
如果您经常需要对数据进行多维度聚合分析(例如既需要按照a列聚合,也要按照b列聚合,同时要按照a和b两列聚合),

您可以使用GROUPING SETS语句进行多维度聚合分析,避免多次使用UNION ALL影响性能

SELECT [ ALL | DISTINCT ]

{ * | projectItem [, projectItem ]* }

FROM tableExpression

GROUP BY

[GROUPING SETS { groupItem [, groupItem ]* } ];

去重语句
去重的方案通常有两种:
保留第一条。
保留最后一条。
说明 ORDER BY后的时间属性字段必须在源表中定义。

     由于SQL没有直接去重的语法,因此我们使用SQL的ROW_NUMBER OVER WINDOW功能实现去重。

ROW_NUMBER OVER WINDOW与TopN语句方法类似,可以理解为一种特殊的TopN。
语法:

SELECT *
FROM (
SELECT *,
ROW_NUMBER() OVER ([PARTITION BY col1[, col2…]
ORDER BY timeAttributeCol [asc|desc]) AS rownum
FROM table_name)
WHERE rownum = 1;

参数说明:
ROW_NUMBER():计算行号,行号计算从1开始。
PARTITION BY col1[, col2…]:指定分区的列,即去重的Key,也可以不指定分区的列。
ORDER BY timeAttributeCol [asc|desc]):指定排序的列,必须是时间属性字段(Processing Time或Event Time)。可以指定为顺序(Keep First Row)或倒序(Keep Last Row)。
外层查询rownum必须为= 1或者<= 1。条件必须是AND,且不能存在Undeterministic的UDF的条件。
如上语法所示,去重需要两层Query:
子查询中:使用ROW_NUMBER(),按照时间属性列对数据进行排序编号。
外层查询中:对排名进行过滤,只取第一条,达到去重的目的。时间列排序方向可以为:
顺序:deduplicate keep first row。
倒序:deduplicate keep last row。
当排序字段是Processing Time列时,Flink会按系统时间去重,其每次运行结果不确定。当排序字段是Event Time列时,Flink会按业务时间去重,其每次运行结果是确定的。
13.1 Deduplicate Keep First Row
保留首行的去重策略,即保留指定Key下第一条出现的数据,之后出现在该Key下的数据会被丢弃掉。因为其State中只存储了Key数据,因此性能较优。示例如下。

     语法:

SELECT *
FROM (
SELECT *,
ROW_NUMBER() OVER (PARTITION BY b ORDER BY proctime) as rowNum
FROM T
)
WHERE rowNum = 1;

本例中,将T表按照b字段进行去重,并按照系统时间保留第一条数据。proctime在以上示例中是源表T中的一个具有Processing Time属性的字段。
如果您按照系统时间去重,也可以将proctime字段简化成PROCTIME()函数进行调用,可以省略proctime字段的声明。
13.2 Deduplicate Keep Last Row

注意 LastRow不支持使用Event Time进行开窗。
LastRow的作用也是去重,且只保留该主键下最后一条出现的数据。其性能略胜于LAST_VALUE函数,示例如下。

SELECT *
FROM (
SELECT *,
ROW_NUMBER() OVER (PARTITION BY b, d ORDER BY proctime DESC) as rowNum
FROM T
)
WHERE rowNum = 1;

14 条件表达式
14.1 CASE表达式
语法:

CASE value WHEN value1 [, value11 ]* THEN result1
[ WHEN valueN [, valueN1 ]* THEN resultN ]* [ ELSE resultZ ]
END

CASE WHEN condition1 THEN result1
[ WHEN conditionN THEN resultN ]* [ ELSE resultZ ]
END
语法说明

当value值为value1则返回result1,都不满足则返回resultZ,若没有else语句,则返回null。
当condition1为true时返回result1,都不满足则返回resultZ,若没有else语句,则返回null。
注意事项

所有result的类型都必须一致。
所有condition类型都必须是布尔类型。
当没有满足的分支时,若指定else语句,则返回else的值,若没有else语句,则返回null。
14.2 NULLIF 表达式
语法:

NULLIF(value, value)
语法说明

如果值相同,则返回NULL。 例如,NULLIF(5,5)返回NULL; NULLIF(5,0)返回5。

注意事项

无。

示例

当units等于3时返回null,否则返回units

14.3 COALESCE表达式
语法格式:
COALESCE(value, value [, value ]* )
语法说明

返回从左到右第一个不为NULL的参数的值。

注意事项

所有value的类型都必须一致。

示例:

五、1.11版本的flink新功能
简化 connector 参数

CREATE TABLE user_behavior (

) WITH (
‘connector’=‘kafka’,
‘topic’=‘user_behavior’,
‘scan.startup.mode’=‘earliest-offset’,
‘properties.zookeeper.connect’=‘localhost:2181’,
‘properties.bootstrap.servers’=‘localhost:9092’,
‘format’=‘json’
);

内置 connectors

对于想要测试 Flink SQL 性能的用户,可以使用 blackhole 作为 sink;

对于调试排错场景,print sink 会将计算结果打到标准输出(比如集群环境下就会打到 taskmanager.out 文件),使得定位问题的成本大大降低。

在外部 connector 环境还没有 ready 时,用户可以选择 datagen source 和 print sink 快速构建 pipeline 熟悉 Flink SQL;

LIKE 语法优化
Flink SQL 1.11 支持用户从已定义好的 table DDL 中快速 “fork” 自己的版本并进一步修改 watermark 或者 connector 等属性。

比如下面这张 base_table 上想加一个 watermark,在 Flink 1.11 版本之前,用户只能重新将表声明一遍,并加入自己的修改,可谓 “牵一发而动全身”。

从 Flink 1.11 开始,用户只需要使用 CREATE TABLE LIKE 语法就可以完成之前的操作。

六、参考链接
1. https://help.aliyun.com/document_detail/103076.html?spm=a2c4g.11186623.6.688.372e7f6fBRHNRu
2. https://iteblog.blog.csdn.net/article/details/108656414
3. https://zhuanlan.zhihu.com/p/183234177
4. 华为云-flinksqlref-zh.pdf
5. https://support.huaweicloud.com/sqlref-flink-dli/dli_08_0103.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值