小T导读:尽管时序数据处理的特点是以写操作为主,读操作为辅,但查询需求也不容忽视。为方便用户上手,TDengine 采用 SQL 作为查询语言,主要查询功能包括单列及多列数据查询、数值列及聚合结果的四则运算、时间戳对齐的连接查询操作等,本文将就部分查询细则做分析。
通配符和标签列
通配符 * 可以用于代指全部列。对于普通表和子表,结果中只有普通列;对于超级表,还包含了 Tag 列。
SELECT * FROM d1001;
复制
通配符支持表名前缀,以下两个 SQL 语句均为返回全部的列:
SELECT * FROM d1001;
SELECT d1001.* FROM d1001;
复制
在 JOIN 查询中,带表名前缀的 * 和不带前缀 * 返回的结果有差别, * 返回全部表的所有列数据(不包含标签),而带表名前缀的通配符,则只返回该表的列数据。
SELECT * FROM d1001, d1003 WHERE d1001.ts=d1003.ts;
SELECT d1001.* FROM d1001,d1003 WHERE d1001.ts = d1003.ts;
复制
此外,在超级表和子表的查询中我们也可以指定标签列,且标签列的值会与普通列的数据一起返回。
SELECT location, groupid, current FROM d1001 LIMIT 2;
复制
结果去重
DISTINCT 关键字可以对结果集中的一列或多列进行去重,去除的列既可以是标签列也可以是数据列。
对标签列去重:
SELECT DISTINCT tag_name [, tag_name ...] FROM stb_name;
复制
对数据列去重:
SELECT DISTINCT col_name [, col_name ...] FROM tb_name;
复制
cfg 文件中的配置参数 maxNumOfDistinctRes 将对 DISTINCT 能够输出的数据行数进行限制。其最小值是 100000,最大值是 100000000,默认值是 10000000。如果实际计算结果超出了这个限制,那么会仅输出这个数量范围内的部分。 由于浮点数天然的精度机制原因,在特定情况下,对 FLOAT 和 DOUBLE 列使用 DISTINCT 并不能保证输出值的完全唯一性。
特殊功能
下面的命令可以获取当前所在的数据库 database(),如果登录的时候没有指定默认数据库,且没有使用 USE 命令切换数据,则返回 NULL。
SELECT DATABASE();
复制
获取服务器和客户端版本号:
SELECT CLIENT_VERSION();
SELECT SERVER_VERSION()
复制
SELECT SERVER_STATUS();
复制
正式表达式过滤
WHERE (column|tbname) match/MATCH/nmatch/NMATCH _regex_
复制
确保使用的正则表达式符合 POSIX 的规范,具体规范内容可参见 Regular Expressions:https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html
CASE 表达式
CASE value WHEN compare_value THEN result [WHEN compare_value THEN result ...] [ELSE result] END
CASE WHEN condition THEN result [WHEN condition THEN result ...] [ELSE result] END
复制
某设备有三个状态码,显示其状态,语句如下:
SELECT CASE dev_status WHEN 1 THEN 'Running' WHEN 2 THEN 'Warning' WHEN 3 THEN 'Downtime' ELSE 'Unknown' END FROM dev_table;
复制
统计智能电表的电压平均值,当电压小于 200 或大于 250 时认为是统计有误,修正其值为 220,语句如下:
SELECT AVG(CASE WHEN voltage < 200 or voltage > 250 THEN 220 ELSE voltage END) FROM meters;
复制
JOIN 子句
普通表与普通表之间的 JOIN 操作:
SELECT *
FROM temp_tb_1 t1, pressure_tb_1 t2
WHERE t1.ts = t2.ts
复制
复制
超级表与超级表之间的 JOIN 操作:
SELECT *
FROM temp_stable t1, temp_stable t2
WHERE t1.ts = t2.ts AND t1.deviceid = t2.deviceid AND t1.status=0;
复制
子表与超级表之间的 JOIN 操作:
SELECT *
FROM temp_ctable t1, temp_stable t2
WHERE t1.ts = t2.ts AND t1.deviceid = t2.deviceid AND t1.status=0;
复制
类似地,也可以对多个子查询的查询结果进行 JOIN 操作。
嵌套查询
从 2.2.0.0 版本开始,TDengine 的查询引擎开始支持在 FROM 子句中使用非关联子查询(“非关联”的意思是,子查询不会用到父查询中的参数),也即在普通 SELECT 语句的 tb_name_list 位置,用一个独立的 SELECT 语句来代替(这一 SELECT 语句被包含在英文圆括号内),于是完整的嵌套查询 SQL 语句形如:
SELECT ... FROM (SELECT ... FROM ...) ...;
复制
内层查询的返回结果将作为“虚拟表”供外层查询使用,此虚拟表建议起别名,以便于外层查询中方便引用。 在内层和外层查询中,都支持普通的表间/超级表间 JOIN。内层查询的计算结果也可以再参与数据子表的 JOIN 操作。 内层查询支持的功能特性与非嵌套的查询语句能力是一致的:内层查询的 ORDER BY 子句一般没有意义,建议避免这样的写法以免无谓的资源消耗。 与非嵌套的查询语句相比,外层查询所能支持的功能特性存在如下限制(计算函数部分):
如果内层查询的结果数据未提供时间戳,那么计算过程隐式依赖时间戳的函数在外层会无法正常工作。例如:INTERP, DERIVATIVE, IRATE, LAST_ROW, FIRST, LAST, TWA, STATEDURATION, TAIL, UNIQUE。 如果内层查询的结果数据不是按时间戳有序,那么计算过程依赖数据按时间有序的函数在外层会无法正常工作。例如:LEASTSQUARES, ELAPSED, INTERP, DERIVATIVE, IRATE, TWA, DIFF, STATECOUNT, STATEDURATION, CSUM, MAVG, TAIL, UNIQUE。 计算过程需要两遍扫描的函数,在外层查询中无法正常工作。例如:此类函数包括:PERCENTILE。
写在最后
往
期
推
荐