数据查询

查询语法:

  1. SELECT select_expr [, select_expr ...]
  2. FROM {tb_name_list}
  3. [WHERE where_condition]
  4. [INTERVAL (interval_val [, interval_offset])]
  5. [SLIDING sliding_val]
  6. [FILL fill_val]
  7. [GROUP BY col_list]
  8. [ORDER BY col_list { DESC | ASC }]
  9. [SLIMIT limit_val [, SOFFSET offset_val]]
  10. [LIMIT limit_val [, OFFSET offset_val]]
  11. [>> export_file];

SELECT子句

一个选择子句可以是联合查询(UNION)和另一个查询的子查询(SUBQUERY)。

通配符

通配符 * 可以用于代指全部列。对于普通表,结果中只有普通列。

  1. taos> SELECT * FROM d1001;
  2. ts | current | voltage | phase |
  3. ======================================================================================
  4. 2018-10-03 14:38:05.000 | 10.30000 | 219 | 0.31000 |
  5. 2018-10-03 14:38:15.000 | 12.60000 | 218 | 0.33000 |
  6. 2018-10-03 14:38:16.800 | 12.30000 | 221 | 0.31000 |
  7. Query OK, 3 row(s) in set (0.001165s)

在针对超级表,通配符包含 标签列

  1. taos> SELECT * FROM meters;
  2. ts | current | voltage | phase | location | groupid |
  3. =====================================================================================================================================
  4. 2018-10-03 14:38:05.500 | 11.80000 | 221 | 0.28000 | Beijing.Haidian | 2 |
  5. 2018-10-03 14:38:16.600 | 13.40000 | 223 | 0.29000 | Beijing.Haidian | 2 |
  6. 2018-10-03 14:38:05.000 | 10.80000 | 223 | 0.29000 | Beijing.Haidian | 3 |
  7. 2018-10-03 14:38:06.500 | 11.50000 | 221 | 0.35000 | Beijing.Haidian | 3 |
  8. 2018-10-03 14:38:04.000 | 10.20000 | 220 | 0.23000 | Beijing.Chaoyang | 3 |
  9. 2018-10-03 14:38:16.650 | 10.30000 | 218 | 0.25000 | Beijing.Chaoyang | 3 |
  10. 2018-10-03 14:38:05.000 | 10.30000 | 219 | 0.31000 | Beijing.Chaoyang | 2 |
  11. 2018-10-03 14:38:15.000 | 12.60000 | 218 | 0.33000 | Beijing.Chaoyang | 2 |
  12. 2018-10-03 14:38:16.800 | 12.30000 | 221 | 0.31000 | Beijing.Chaoyang | 2 |
  13. Query OK, 9 row(s) in set (0.002022s)

通配符支持表名前缀,以下两个SQL语句均为返回全部的列:

  1. SELECT * FROM d1001;
  2. SELECT d1001.* FROM d1001;

在Join查询中,带前缀的*和不带前缀*返回的结果有差别, *返回全部表的所有列数据(不包含标签),带前缀的通配符,则只返回该表的列数据。

  1. taos> SELECT * FROM d1001, d1003 WHERE d1001.ts=d1003.ts;
  2. ts | current | voltage | phase | ts | current | voltage | phase |
  3. ==================================================================================================================================
  4. 2018-10-03 14:38:05.000 | 10.30000| 219 | 0.31000 | 2018-10-03 14:38:05.000 | 10.80000| 223 | 0.29000 |
  5. Query OK, 1 row(s) in set (0.017385s)
  1. taos> SELECT d1001.* FROM d1001,d1003 WHERE d1001.ts = d1003.ts;
  2. ts | current | voltage | phase |
  3. ======================================================================================
  4. 2018-10-03 14:38:05.000 | 10.30000 | 219 | 0.31000 |
  5. Query OK, 1 row(s) in set (0.020443s)

在使用SQL函数来进行查询过程中,部分SQL函数支持通配符操作。其中的区别在于: count(\*)函数只返回一列。firstlastlast_row函数则是返回全部列。

  1. taos> SELECT COUNT(*) FROM d1001;
  2. count(*) |
  3. ========================
  4. 3 |
  5. Query OK, 1 row(s) in set (0.001035s)
  1. taos> SELECT FIRST(*) FROM d1001;
  2. first(ts) | first(current) | first(voltage) | first(phase) |
  3. =========================================================================================
  4. 2018-10-03 14:38:05.000 | 10.30000 | 219 | 0.31000 |
  5. Query OK, 1 row(s) in set (0.000849s)
标签列

从 2.0.14 版本开始,支持在普通表的查询中指定 标签列,且标签列的值会与普通列的数据一起返回。

  1. taos> SELECT location, groupid, current FROM d1001 LIMIT 2;
  2. location | groupid | current |
  3. ======================================================================
  4. Beijing.Chaoyang | 2 | 10.30000 |
  5. Beijing.Chaoyang | 2 | 12.60000 |
  6. Query OK, 2 row(s) in set (0.003112s)

注意:普通表的通配符 * 中并不包含 标签列

获取标签列的去重取值

从 2.0.15 版本开始,支持在超级表查询标签列时,指定 distinct 关键字,这样将返回指定标签列的所有不重复取值。

  1. SELECT DISTINCT tag_name FROM stb_name;

注意:目前 distinct 关键字只支持对超级表的标签列进行去重,而不能用于普通列。

结果集列名

SELECT子句中,如果不指定返回结果集合的列名,结果集列名称默认使用SELECT子句中的表达式名称作为列名称。此外,用户可使用AS来重命名返回结果集合中列的名称。例如:

  1. taos> SELECT ts, ts AS primary_key_ts FROM d1001;
  2. ts | primary_key_ts |
  3. ====================================================
  4. 2018-10-03 14:38:05.000 | 2018-10-03 14:38:05.000 |
  5. 2018-10-03 14:38:15.000 | 2018-10-03 14:38:15.000 |
  6. 2018-10-03 14:38:16.800 | 2018-10-03 14:38:16.800 |
  7. Query OK, 3 row(s) in set (0.001191s)

但是针对first(*)last(*)last_row(*)不支持针对单列的重命名。

隐式结果列

Select_exprs可以是表所属列的列名,也可以是基于列的函数表达式或计算式,数量的上限256个。当用户使用了intervalgroup by tags的子句以后,在最后返回结果中会强制返回时间戳列(第一列)和group by子句中的标签列。后续的版本中可以支持关闭group by子句中隐式列的输出,列输出完全由select子句控制。

表(超级表)列表

FROM关键字后面可以是若干个表(超级表)列表,也可以是子查询的结果。 如果没有指定用户的当前数据库,可以在表名称之前使用数据库的名称来指定表所属的数据库。例如:power.d1001 方式来跨库使用表。

  1. SELECT * FROM power.d1001;
  2. ------------------------------
  3. USE power;
  4. SELECT * FROM d1001;

特殊功能

部分特殊的查询功能可以不使用FROM子句执行。获取当前所在的数据库 database()

  1. taos> SELECT DATABASE();
  2. database() |
  3. =================================
  4. power |
  5. Query OK, 1 row(s) in set (0.000079s)

如果登录的时候没有指定默认数据库,且没有使用use命令切换数据,则返回NULL。

  1. taos> SELECT DATABASE();
  2. database() |
  3. =================================
  4. NULL |
  5. Query OK, 1 row(s) in set (0.000184s)

获取服务器和客户端版本号:

  1. taos> SELECT CLIENT_VERSION();
  2. client_version() |
  3. ===================
  4. 2.0.0.0 |
  5. Query OK, 1 row(s) in set (0.000070s)
  6. taos> SELECT SERVER_VERSION();
  7. server_version() |
  8. ===================
  9. 2.0.0.0 |
  10. Query OK, 1 row(s) in set (0.000077s)

服务器状态检测语句。如果服务器正常,返回一个数字(例如 1)。如果服务器异常,返回error code。该SQL语法能兼容连接池对于TDengine状态的检查及第三方工具对于数据库服务器状态的检查。并可以避免出现使用了错误的心跳检测SQL语句导致的连接池连接丢失的问题。

  1. taos> SELECT SERVER_STATUS();
  2. server_status() |
  3. ==================
  4. 1 |
  5. Query OK, 1 row(s) in set (0.000074s)
  6. taos> SELECT SERVER_STATUS() AS status;
  7. status |
  8. ==============
  9. 1 |
  10. Query OK, 1 row(s) in set (0.000081s)

TAOS SQL中特殊关键词

TBNAME: 在超级表查询中可视为一个特殊的标签,代表查询涉及的子表名
_c0: 表示表(超级表)的第一列

小技巧

获取一个超级表所有的子表名及相关的标签信息:

  1. SELECT TBNAME, location FROM meters;

统计超级表下辖子表数量:

  1. SELECT COUNT(TBNAME) FROM meters;

以上两个查询均只支持在Where条件子句中添加针对标签(TAGS)的过滤条件。例如:

  1. taos> SELECT TBNAME, location FROM meters;
  2. tbname | location |
  3. ==================================================================
  4. d1004 | Beijing.Haidian |
  5. d1003 | Beijing.Haidian |
  6. d1002 | Beijing.Chaoyang |
  7. d1001 | Beijing.Chaoyang |
  8. Query OK, 4 row(s) in set (0.000881s)
  9. taos> SELECT COUNT(tbname) FROM meters WHERE groupId > 2;
  10. count(tbname) |
  11. ========================
  12. 2 |
  13. Query OK, 1 row(s) in set (0.001091s)
  • 可以使用 * 返回所有列,或指定列名。可以对数字列进行四则运算,可以给输出的列取列名
  • WHERE 语句可以使用各种逻辑判断来过滤数字值,或使用通配符来过滤字符串
  • 输出结果缺省按首列时间戳升序排序,但可以指定按降序排序( _c0 指首列时间戳)。使用 ORDER BY 对其他字段进行排序为非法操作。
  • 参数 LIMIT 控制输出条数,OFFSET 指定从第几条开始输出。LIMIT/OFFSET 对结果集的执行顺序在 ORDER BY 之后。
  • 参数 SLIMIT 控制由 GROUP BY 指令划分的每个分组中的输出条数。
  • 通过”>>”输出结果可以导出到指定文件

支持的条件过滤操作

OperationNoteApplicable Data Types
>larger thantimestamp and all numeric types
<smaller thantimestamp and all numeric types
>=larger than or equal totimestamp and all numeric types
<=smaller than or equal totimestamp and all numeric types
=equal toall types
<>not equal toall types
between andwithin a certain rangetimestamp and all numeric types
%match with any char sequencesbinary nchar
_match with a single charbinary nchar
  1. 同时进行多个字段的范围过滤,需要使用关键词 AND 来连接不同的查询条件,暂不支持 OR 连接的不同列之间的查询过滤条件。
  2. 针对单一字段的过滤,如果是时间过滤条件,则一条语句中只支持设定一个;但针对其他的(普通)列或标签列,则可以使用 OR 关键字进行组合条件的查询过滤。例如:((value > 20 AND value < 30) OR (value < 12)) 。
  3. 从 2.0.17 版本开始,条件过滤开始支持 BETWEEN AND 语法,例如 WHERE col2 BETWEEN 1.5 AND 3.25 表示查询条件为“1.5 ≤ col2 ≤ 3.25”。

SQL 示例

  • 对于下面的例子,表tb1用以下语句创建

    1. CREATE TABLE tb1 (ts TIMESTAMP, col1 INT, col2 FLOAT, col3 BINARY(50));
  • 查询tb1刚过去的一个小时的所有记录

    1. SELECT * FROM tb1 WHERE ts >= NOW - 1h;
  • 查询表tb1从2018-06-01 08:00:00.000 到2018-06-02 08:00:00.000时间范围,并且col3的字符串是’nny’结尾的记录,结果按照时间戳降序

    1. SELECT * FROM tb1 WHERE ts > '2018-06-01 08:00:00.000' AND ts <= '2018-06-02 08:00:00.000' AND col3 LIKE '%nny' ORDER BY ts DESC;
  • 查询col1与col2的和,并取名complex, 时间大于2018-06-01 08:00:00.000, col2大于1.2,结果输出仅仅10条记录,从第5条开始

    1. SELECT (col1 + col2) AS 'complex' FROM tb1 WHERE ts > '2018-06-01 08:00:00.000' AND col2 > 1.2 LIMIT 10 OFFSET 5;
  • 查询过去10分钟的记录,col2的值大于3.14,并且将结果输出到文件 /home/testoutpu.csv.

    1. SELECT COUNT(*) FROM tb1 WHERE ts >= NOW - 10m AND col2 > 3.14 >> /home/testoutpu.csv;