子查询
子查询(也称为内部查询或嵌套查询)是在查询内部执行的查询。子查询可以用在 SELECT
、FROM
、WHERE
和 HAVING
子句中。
子查询运算符
[ NOT ] EXISTS
EXISTS
运算符返回所有行,其中相关子查询对于该行产生一个或多个匹配。 NOT EXISTS
返回所有行,其中相关子查询对于该行产生零个匹配。仅支持相关子查询。
语法
[ NOT ] IN
IN
运算符返回所有行,其中给定表达式的值可以在相关子查询的结果中找到。 NOT IN
返回所有行,其中给定表达式的值不能在子查询或值列表的结果中找到。
语法
expression [NOT] IN (subquery|list-literal)
示例
使用查询查看 IN
示例
SELECT
time,
room,
temp
FROM
home
WHERE
room IN (
SELECT
DISTINCT room
FROM
home_actions
)
SELECT
time,
room,
temp
FROM
home
WHERE
room NOT IN (
SELECT
DISTINCT room
FROM
home_actions
)
使用列表字面量查看 IN
示例
SELECT
time,
room,
temp
FROM home
WHERE room IN ('Bathroom', 'Bedroom', 'Kitchen')
SELECT
time,
room,
temp
FROM home
WHERE room NOT IN ('Bathroom', 'Bedroom', 'Kitchen')
SELECT 子句子查询
SELECT
子句子查询使用内部查询返回的值作为外部查询的SELECT
列表的一部分。该SELECT
子句仅支持返回单个值的scalar subqueries
(标量子查询)。返回的值对于每一行可以不同。
语法
SELECT [expression1[, expression2, ..., expressionN],] (<subquery>)
SELECT
子句子查询可以用作JOIN
操作的替代。
示例
FROM 子句子查询
FROM
子句子查询返回一个结果集,然后外部查询对该结果集进行查询和操作。
语法
SELECT expression1[, expression2, ..., expressionN] FROM (<subquery>)
示例
查看FROM
子句子查询示例
以下查询返回每个房间的最大值的平均值。内部查询返回每个房间的每个字段的最高值。外部查询使用内部查询的结果,并返回每个字段的平均最大值。
SELECT
AVG(max_co) AS avg_max_co,
AVG(max_hum) AS avg_max_hum,
AVG(max_temp) AS avg_max_temp
FROM
(
SELECT
room,
MAX(co) AS max_co,
MAX(hum) AS max_hum,
MAX(temp) AS max_temp
FROM
home
GROUP BY
room
)
内部查询结果
房间 | max_co | max_hum | max_temp |
---|
客厅 | 17 | 36.4 | 22.8 |
厨房 | 26 | 36.9 | 23.3 |
外部查询结果
avg_max_co | avg_max_hum | avg_max_temp |
---|
21.5 | 36.7 | 23.1 |
WHERE 子句子查询
WHERE
子句子查询将表达式与子查询的结果进行比较,并返回true或false。评估结果为false或NULL的行将从结果中过滤掉。WHERE
子句支持相关和非相关子查询,以及标量和非标量子查询(取决于谓词表达式中使用的运算符)。
语法
SELECT
expression1[, expression2, ..., expressionN]
FROM
<measurement>
WHERE
expression operator (<subquery>)
示例
带有标量子查询的WHERE
子句
以下查询返回所有temp
值高于所有temp
平均值的数据点。子查询返回平均temp
值。
SELECT
*
FROM
home
WHERE
temp > (
SELECT
AVG(temp)
FROM
home
)
内部查询结果
AVG(home.temp) |
---|
22.396153846153844 |
外部查询结果
co | hum | 房间 | temp | 时间 |
---|
0 | 36.2 | 厨房 | 23 | 2022-01-01T09:00:00Z |
0 | 36.1 | 厨房 | 22.7 | 2022-01-01T10:00:00Z |
0 | 36 | 厨房 | 22.4 | 2022-01-01T11:00:00Z |
0 | 36 | 厨房 | 22.5 | 2022-01-01T12:00:00Z |
1 | 36.5 | 厨房 | 22.8 | 2022-01-01T13:00:00Z |
1 | 36.3 | 厨房 | 22.8 | 2022-01-01T14:00:00Z |
3 | 36.2 | 厨房 | 22.7 | 2022-01-01T15:00:00Z |
7 | 36 | 厨房 | 22.4 | 2022-01-01T16:00:00Z |
9 | 36 | 厨房 | 22.7 | 2022-01-01T17:00:00Z |
18 | 36.9 | 厨房 | 23.3 | 2022-01-01T18:00:00Z |
22 | 36.6 | 厨房 | 23.1 | 2022-01-01T19:00:00Z |
26 | 36.5 | 厨房 | 22.7 | 2022-01-01T20:00:00Z |
0 | 36 | 客厅 | 22.4 | 2022-01-01T13:00:00Z |
4 | 36 | 客厅 | 22.4 | 2022-01-01T16:00:00Z |
5 | 35.9 | 客厅 | 22.6 | 2022-01-01T17:00:00Z |
9 | 36.2 | 客厅 | 22.8 | 2022-01-01T18:00:00Z |
14 | 36.3 | 客厅 | 22.5 | 2022-01-01T19:00:00Z |
带有非标量子查询的WHERE
子句
非标量子查询必须使用[NOT] IN
或[NOT] EXISTS
运算符,并且只能返回一个列。返回列中的值被评估为列表。
以下查询返回所有与home_actions
测量中warn
级别警报相同的时戳关联的home
测量中的数据点。
SELECT
*
FROM
home
WHERE
time IN (
SELECT
DISTINCT time
FROM
home_actions
WHERE
level = 'warn'
)
内部查询结果
时间 |
---|
2022-01-01T18:00:00Z |
2022-01-01T19:00:00Z |
2022-01-01T20:00:00Z |
外部查询结果
co | hum | 房间 | temp | 时间 |
---|
18 | 36.9 | 厨房 | 23.3 | 2022-01-01T18:00:00Z |
9 | 36.2 | 客厅 | 22.8 | 2022-01-01T18:00:00Z |
26 | 36.5 | 厨房 | 22.7 | 2022-01-01T20:00:00Z |
17 | 36.4 | 客厅 | 22.2 | 2022-01-01T20:00:00Z |
22 | 36.6 | 厨房 | 23.1 | 2022-01-01T19:00:00Z |
14 | 36.3 | 客厅 | 22.5 | 2022-01-01T19:00:00Z |
HAVING 子句子查询
HAVING
子句子查询比较SELECT子句中返回的聚合值表达式与子查询结果,并返回true或false。评估结果为false或NULL的行将从结果中过滤。HAVING子句支持相关和非相关子查询以及标量和非标量子查询(取决于谓词表达式中使用的运算符)。
语法
SELECT
aggregate_expression1[, aggregate_expression2, ..., aggregate_expressionN]
FROM
<measurement>
WHERE
<conditional_expression>
GROUP BY
column_expression1[, column_expression2, ..., column_expressionN]
HAVING
expression operator (<subquery>)
示例
HAVING
子句与标量子查询
以下查询返回所有两小时时间块的平均temp
值大于中位temp
值。
SELECT
DATE_BIN(INTERVAL '2 hours', time) AS "2-hour block",
AVG(temp) AS avg_temp
FROM
home
GROUP BY
1
HAVING
avg_temp > (
SELECT
MEDIAN(temp)
FROM
home
)
内部查询结果
外部查询结果
两小时块 | avg_temp |
---|
2022-01-01T12:00:00Z | 22.475 |
2022-01-01T16:00:00Z | 22.525 |
2022-01-01T18:00:00Z | 22.925 |
2022-01-01T14:00:00Z | 22.525 |
HAVING
子句与非标量子查询
非标量子查询必须使用[NOT] IN
或[NOT] EXISTS
运算符,并且只能返回一个列。返回列中的值被评估为列表。
以下查询返回在时间窗口相关的time
值也与home_actions
测量中的警告相关联的2小时时间窗口内的最大co
和temp
值。
SELECT
date_bin(INTERVAL '2 hours', time) AS "2-hour block",
max(co) AS max_co,
max(temp) as max_temp
FROM
home
GROUP BY
1,
room
HAVING
"2-hour block" IN (
SELECT
DISTINCT time
FROM
home_actions
WHERE
level = 'warn'
)
内部查询结果
时间 |
---|
2022-01-01T18:00:00Z |
2022-01-01T19:00:00Z |
2022-01-01T20:00:00Z |
外部查询结果
两小时块 | max_co | max_temp |
---|
2022-01-01T18:00:00Z | 14 | 22.8 |
2022-01-01T18:00:00Z | 22 | 23.3 |
2022-01-01T20:00:00Z | 17 | 22.2 |
2022-01-01T20:00:00Z | 26 | 22.7 |
子查询类别
根据子查询的行为,SQL子查询可以分为以下一种或多种:
在相关子查询中,内部查询依赖于外部查询,使用外部查询的值来生成其结果。相关子查询最多返回一行,因此可能需要在内部查询中执行聚合。
在下面的查询中,内部查询(SELECT temp_avg FROM weather WHERE location = home.room
)依赖于外部查询(SELECT time, room, temp FROM home
)中的数据(home.room
),因此是一个相关子查询。
SELECT
time,
room,
temp
FROM
home
WHERE
temp = (
SELECT
temp_avg
FROM
weather
WHERE
location = home.room
)
因为相关子查询依赖于外部查询,通常必须为外部查询返回的每一行执行,所以相关子查询的性能比非相关子查询低。
在非相关子查询中,内部查询不依赖于外部查询,并独立执行。内部查询首先执行,然后将结果传递给外部查询。
在下面的查询中,内部查询(SELECT MIN(temp_avg) FROM weather
)可以独立于外部查询(SELECT time, temp FROM home
)运行,因此是一个非相关子查询。
SELECT
time,
temp
FROM
home
WHERE
temp < (
SELECT
MIN(temp_avg)
FROM
weather
)
标量子查询
标量子查询返回单个值(一列的一行)。如果没有行返回,子查询返回NULL。
以下示例子查询返回指定列的平均值。这是一个单个标量值。
SELECT * FROM home WHERE co > (SELECT avg(co) FROM home)
非标量子查询
非标量子查询返回0、1或多个行,每行可能包含1或多个列。对于每一列,如果没有值返回,子查询返回NULL。如果没有行符合返回条件,子查询返回0行。
以下示例子查询返回列中的所有不同值。返回多个值。
SELECT * FROM home WHERE room IN (SELECT DISTINCT room FROM home_actions)
支持和反馈
感谢您成为我们社区的一员!我们欢迎并鼓励您对InfluxDB和本文档提供反馈和错误报告。要寻找支持,请使用以下资源
拥有年度或支持合同的客户可以联系InfluxData支持。