在实际应用中,用户可能希望对查询的结果集中某些存在空值的行进行过滤。在 IoTDB 中,可以使用 WITHOUT NULL 子句对结果集中的空值进行过滤,有两种过滤策略:WITHOUT NULL ANY和WITHOUT NULL ALL。不仅如此, WITHOUT NULL 子句支持指定相应列进行过滤。
WITHOUT NULL ANY: 指定的列集中,存在一列为NULL,则满足条件进行过滤
WITHOUT NULL ALL: 指定的列集中,所有列都为NULL,才满足条件进行过滤
默认就是对结果集中的所有列生效,即指定的列集为结果集中的所有列
select * from root.ln.** where time <= 2017-11-01T00:01:00 WITHOUT NULL ANY
select * from root.ln.** where group by ([1,10), 2ms) WITHOUT NULL ALL
只对指定的列集生效
使用 WITHOUT NULL子句对结果集中指定列名的空值进行过滤,下面是一些例子及其说明:
注意,如果指定的列在当前元数据里不存在则会直接过滤掉,这与目前查询列的输出结果是一致的; 如果指定的列存在,但与结果集中输出的列名不匹配,则会报错:
The without null columns don't match the columns queried.If has alias, please use the alias.
比如下面的例子
without null指定的列集中root.test.sg1.s1列在元数据中存在,root.test.sg1.usag列在元数据不存在,则下面查询的without null子句的作用相当于without null all(s1)select * from root.test.sg1 without null all (s1, usag)
without null指定的列集中root.test.sg1.s2列在元数据中存在,但查询的结果集中输出列不包括,所以会报错:The without null columns don't match the columns queried.If has alias, please use the alias.select s1 + s2, s1 - s2, s1 * s2, s1 / s2, s1 % s2 from root.test.sg1 without null all (s1+s2, s2)
select * from root.ln.sg1 WITHOUT NULL ANY(s1)
select * from root.ln.sg1 WITHOUT NULL ANY(s1, s2)
select * from root.ln.sg1 WITHOUT NULL ALL(s1, s2)
指定的列可以为表达式
select s2, - s2, s4, + s4, s2 + s4, s2 - s4, s2 * s4, s2 / s4, s2 % s4 from root.test.sg1 without null all (s2+s4, s2)
select s2, - s2, s4, + s4, s2 + s4, s2 - s4, s2 * s4, s2 / s4, s2 % s4 from root.test.sg1 without null any (s2+s4, s2)
select s1, sin(s2) + cos(s2), cos(sin(s2 + s4) + s2) from root.test.sg1 without null all (sin(s2) + cos(s2), cos(sin(s2 + s4) + s2))
select last_value(*) from root.test.sg1 group by([1,10), 2ms) without null all(last_value(s2), last_value(s3)) align by device
结果示例如下:
IoTDB> select last_value(*) from root.sg1.* group by([1,10), 2ms) without null all(last_value(s2), last_value(s3)) align by device +-----------------------------+-----------+--------------+--------------+--------------+ | Time| Device|last_value(s1)|last_value(s2)|last_value(s3)| +-----------------------------+-----------+--------------+--------------+--------------+ |1970-01-01T08:00:00.001+08:00|root.sg1.d1| 1.0| 2.0| null| |1970-01-01T08:00:00.003+08:00|root.sg1.d1| 3.0| 4.0| null| |1970-01-01T08:00:00.001+08:00|root.sg1.d2| 1.0| 1.0| 1.0| +-----------------------------+-----------+--------------+--------------+--------------+ Total line number = 3 It costs 0.007s
指定的列名是与输出结果的列名对应,目前without null子句不支持指定某设备的某列,会报错:The without null columns don't match the columns queried.If has alias, please use the alias. 比如下面这个查询例子,指定last_value(root.sg1.d1.s3)为null的行进行过滤,目前是不支持的。
select last_value(*) from root.test.sg1 group by([1,10), 2ms) without null all(last_value(`root.sg1.d1.s3`)) align by device
select avg(s4), sum(s2) from root.test.sg1 group by ([1,10), 2ms) without null all(sum(s2))
select avg(s4), sum(s2), count(s3) from root.test.sg1 group by ([1,10), 2ms) without null all(avg(s4), sum(s2))
假设下面的查询输出的结果列为“root.test.sg1.s2”, “root.test.sg1.s3”, “root.test.sg2.s2”, “root.test.sg2.s3”四个,可以使用全路径名指定相应列进行过滤,比如下面的例子:
root.test.sg1.s2, root.test.sg2.s3两列都为null则过滤select s2, s3 from root.test.** without null all(root.test.sg1.s2, root.test.sg2.s3)
root.test.sg1.s2, root.test.sg1.s3, root.test.sg2.s3三列都为null则过滤select s2, s3 from root.test.** without null all(root.test.sg1.s2, s3)
without null 子句后的列名为对齐序列列名CREATE ALIGNED TIMESERIES root.test.sg3(s5 INT32, s6 BOOLEAN, s7 DOUBLE, s8 INT32) select sg1.s1, sg1.s2, sg2.s3, sg3.* from root.test without null all (sg3.s5, sg3.s6, sg2.s3)