子查询
子查询(也称为内部查询或嵌套查询)是在查询内部进行的查询。子查询可以用于 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
子句仅支持标量子查询,这些子查询每次执行内部查询时返回单个值。返回的值对于每行可以是唯一的。
语法
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
)
内部查询结果
room | max_co | max_hum | max_temp |
---|
Living Room | 17 | 36.4 | 22.8 |
Kitchen | 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
子句子查询可以用作 JOIN
操作的替代方法。
示例
带有标量子查询的 WHERE
子句
以下查询返回 temp
值高于所有 temp
值的平均值的所有点。子查询返回平均 temp
值。
SELECT
*
FROM
home
WHERE
temp > (
SELECT
AVG(temp)
FROM
home
)
内部查询结果
AVG(home.temp) |
---|
22.396153846153844 |
外部查询结果
co | hum | room | temp | time |
---|
0 | 36.2 | Kitchen | 23 | 2022-01-01T09:00:00Z |
0 | 36.1 | Kitchen | 22.7 | 2022-01-01T10:00:00Z |
0 | 36 | Kitchen | 22.4 | 2022-01-01T11:00:00Z |
0 | 36 | Kitchen | 22.5 | 2022-01-01T12:00:00Z |
1 | 36.5 | Kitchen | 22.8 | 2022-01-01T13:00:00Z |
1 | 36.3 | Kitchen | 22.8 | 2022-01-01T14:00:00Z |
3 | 36.2 | Kitchen | 22.7 | 2022-01-01T15:00:00Z |
7 | 36 | Kitchen | 22.4 | 2022-01-01T16:00:00Z |
9 | 36 | Kitchen | 22.7 | 2022-01-01T17:00:00Z |
18 | 36.9 | Kitchen | 23.3 | 2022-01-01T18:00:00Z |
22 | 36.6 | Kitchen | 23.1 | 2022-01-01T19:00:00Z |
26 | 36.5 | Kitchen | 22.7 | 2022-01-01T20:00:00Z |
0 | 36 | Living Room | 22.4 | 2022-01-01T13:00:00Z |
4 | 36 | Living Room | 22.4 | 2022-01-01T16:00:00Z |
5 | 35.9 | Living Room | 22.6 | 2022-01-01T17:00:00Z |
9 | 36.2 | Living Room | 22.8 | 2022-01-01T18:00:00Z |
14 | 36.3 | Living Room | 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'
)
内部查询结果
time |
---|
2022-01-01T18:00:00Z |
2022-01-01T19:00:00Z |
2022-01-01T20:00:00Z |
外部查询结果
co | hum | room | temp | time |
---|
18 | 36.9 | Kitchen | 23.3 | 2022-01-01T18:00:00Z |
9 | 36.2 | Living Room | 22.8 | 2022-01-01T18:00:00Z |
26 | 36.5 | Kitchen | 22.7 | 2022-01-01T20:00:00Z |
17 | 36.4 | Living Room | 22.2 | 2022-01-01T20:00:00Z |
22 | 36.6 | Kitchen | 23.1 | 2022-01-01T19:00:00Z |
14 | 36.3 | Living Room | 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
值大于温度中位数的两个小时时间段。
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
)
内部查询结果
外部查询结果
2 小时时间段 | 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
运算符,并且只能返回单列。返回列中的值被评估为列表。
以下查询返回 2 小时时间窗口内的最大 co
和 temp
值,其中与时间窗口关联的 time
值也与 home_actions
测量中的警告相关联。
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'
)
内部查询结果
time |
---|
2022-01-01T18:00:00Z |
2022-01-01T19:00:00Z |
2022-01-01T20:00:00Z |
外部查询结果
2 小时时间段 | 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 Clustered 和本文档的反馈和错误报告。要获得支持,请使用以下资源
拥有年度或支持合同的客户可以联系 InfluxData 支持。