diff --git a/content/influxdb/cloud-dedicated/reference/sample-data.md b/content/influxdb/cloud-dedicated/reference/sample-data.md index b29378e3e..b7560f642 100644 --- a/content/influxdb/cloud-dedicated/reference/sample-data.md +++ b/content/influxdb/cloud-dedicated/reference/sample-data.md @@ -16,6 +16,7 @@ demonstrate functionality. Use the following sample datasets to replicate provided examples. - [Get started home sensor data](#get-started-home-sensor-data) +- [Home sensor actions data](#home-sensor-actions-data) - [NOAA Bay Area weather data](#noaa-bay-area-weather-data) - [Bitcoin price data](#bitcoin-price-data) - [Random numbers sample data](#random-numbers-sample-data) @@ -68,14 +69,9 @@ to {{< cloud-name >}}. {{% influxdb/custom-timestamps %}} {{% code-placeholders "DATABASE_TOKEN|DATABASE_NAME" %}} ```sh -export INFLUX_HOST=https://cluster-id.influxdb.io -export INFLUX_TOKEN=DATABASE_TOKEN - -INFLUX_DATABASE=DATABASE_NAME - curl --request POST \ - "$INFLUX_HOST/api/v2/write?bucket=$INFLUX_DATABASE&precision=s" \ - --header "Authorization: Bearer $INFLUX_TOKEN" \ + https://cluster-id.influxdb.io/api/v2/write?bucket=DATABASE_NAME&precision=s \ + --header "Authorization: Bearer DATABASE_TOKEN" \ --header "Content-Type: text/plain; charset=utf-8" \ --header "Accept: application/json" \ --data-binary " @@ -116,14 +112,9 @@ home,room=Kitchen temp=22.7,hum=36.5,co=26i 1641067200 {{% influxdb/custom-timestamps %}} {{% code-placeholders "DATABASE_TOKEN|DATABASE_NAME" %}} ```sh -export INFLUX_HOST=https://cluster-id.influxdb.io -export INFLUX_TOKEN=DATABASE_TOKEN - -INFLUX_DATABASE=DATABASE_NAME - curl --request POST \ - "$INFLUX_HOST/write?db=$INFLUX_DATABASE&precision=s" \ - --header "Authorization: Bearer $INFLUX_TOKEN" \ + https://cluster-id.influxdb.io/write?db=DATABASE_NAME&precision=s \ + --header "Authorization: Bearer DATABASE_TOKEN" \ --header "Content-type: text/plain; charset=utf-8" \ --data-binary " home,room=Living\ Room temp=21.1,hum=35.9,co=0i 1641024000 @@ -160,10 +151,119 @@ home,room=Kitchen temp=22.7,hum=36.5,co=26i 1641067200 {{% /code-tab-content %}} {{< /code-tabs-wrapper >}} -Replace the following in the script above: +Replace the following in the sample script: -- `DATABASE_NAME`: your InfluxDB Cloud Dedicated database -- `DATABASE_TOKEN`: a [database token](/influxdb/cloud-dedicated/admin/tokens/) +- {{% code-placeholder-key %}}`DATABASE_NAME`{{% /code-placeholder-key %}}: + your InfluxDB Cloud Dedicated database +- {{% code-placeholder-key %}}`DATABASE_TOKEN`{{% /code-placeholder-key %}}: + a [database token](/influxdb/cloud-dedicated/admin/tokens/) + with _write_ permission to the database + +{{% /expand %}} +{{< /expand-wrapper >}} + +## Home sensor actions data + +Includes hypothetical actions triggered by data in the [Get started home sensor data](#get-started-home-sensor-data) +and is a companion dataset to that sample dataset. +To customize timestamps in the dataset, use the {{< icon "clock" >}} button in +the lower right corner of the page. +This lets you modify the sample dataset to stay within the retention period of +the database you write it to. + +##### Time Range + +**{{% influxdb/custom-timestamps-span %}}2022-01-01T08:00:00Z{{% /influxdb/custom-timestamps-span %}}** +to +**{{% influxdb/custom-timestamps-span %}}2022-01-01T20:00:00Z{{% /influxdb/custom-timestamps-span %}}** +(Customizable) + +##### Schema + +- home_actions (measurement) + - **tags**: + - room + - Kitchen + - Living Room + - action + - alert + - cool + - level + - ok + - warn + - **fields**: + - description (string) + +{{< expand-wrapper >}} +{{% expand "Write home sensor actions data to InfluxDB" %}} + +#### Write the home sensor actions data to InfluxDB + +Use the InfluxDB v2 or v1 API to write the home sensor actions sample data +to {{< cloud-name >}}. + +{{< code-tabs-wrapper >}} +{{% code-tabs %}} +[v2 API](#) +[v1 API](#) +{{% /code-tabs %}} +{{% code-tab-content %}} + +{{% influxdb/custom-timestamps %}} +{{% code-placeholders "DATABASE_TOKEN|DATABASE_NAME" %}} +```sh +curl --request POST \ + https://cluster-id.influxdb.io/api/v2/write?bucket=DATABASE_NAME&precision=s \ + --header "Authorization: Bearer DATABASE_TOKEN" \ + --header "Content-Type: text/plain; charset=utf-8" \ + --header "Accept: application/json" \ + --data-binary ' +home_actions,room=Kitchen,action=cool,level=ok description="Temperature at or above 23°C (23°C). Cooling to 22°C." 1641027600 +home_actions,room=Kitchen,action=cool,level=ok description="Temperature at or above 23°C (23.3°C). Cooling to 22°C." 1641060000 +home_actions,room=Kitchen,action=cool,level=ok description="Temperature at or above 23°C (23.1°C). Cooling to 22°C." 1641063600 +home_actions,room=Kitchen,action=alert,level=warn description="Carbon monoxide level above normal: 18 ppm." 1641060000 +home_actions,room=Kitchen,action=alert,level=warn description="Carbon monoxide level above normal: 22 ppm." 1641063600 +home_actions,room=Kitchen,action=alert,level=warn description="Carbon monoxide level above normal: 26 ppm." 1641067200 +home_actions,room=Living\ Room,action=alert,level=warn description="Carbon monoxide level above normal: 14 ppm." 1641063600 +home_actions,room=Living\ Room,action=alert,level=warn description="Carbon monoxide level above normal: 17 ppm." 1641067200 +' +``` +{{% /code-placeholders %}} +{{% /influxdb/custom-timestamps %}} + +{{% /code-tab-content %}} +{{% code-tab-content %}} + +{{% influxdb/custom-timestamps %}} +{{% code-placeholders "DATABASE_TOKEN|DATABASE_NAME" %}} +```sh +curl --request POST \ + https://cluster-id.influxdb.io/write?db=DATABASE_NAME&precision=s \ + --header "Authorization: Bearer DATABASE_TOKEN" \ + --header "Content-type: text/plain; charset=utf-8" \ + --data-binary ' +home_actions,room=Kitchen,action=cool,level=ok description="Temperature at or above 23°C (23°C). Cooling to 22°C." 1641027600 +home_actions,room=Kitchen,action=cool,level=ok description="Temperature at or above 23°C (23.3°C). Cooling to 22°C." 1641060000 +home_actions,room=Kitchen,action=cool,level=ok description="Temperature at or above 23°C (23.1°C). Cooling to 22°C." 1641063600 +home_actions,room=Kitchen,action=alert,level=warn description="Carbon monoxide level above normal: 18 ppm." 1641060000 +home_actions,room=Kitchen,action=alert,level=warn description="Carbon monoxide level above normal: 22 ppm." 1641063600 +home_actions,room=Kitchen,action=alert,level=warn description="Carbon monoxide level above normal: 26 ppm." 1641067200 +home_actions,room=Living\ Room,action=alert,level=warn description="Carbon monoxide level above normal: 14 ppm." 1641063600 +home_actions,room=Living\ Room,action=alert,level=warn description="Carbon monoxide level above normal: 17 ppm." 1641067200 +' +``` +{{% /code-placeholders %}} +{{% /influxdb/custom-timestamps %}} + +{{% /code-tab-content %}} +{{< /code-tabs-wrapper >}} + +Replace the following in the sample script: + +- {{% code-placeholder-key %}}`DATABASE_NAME`{{% /code-placeholder-key %}}: + your InfluxDB Cloud Dedicated database +- {{% code-placeholder-key %}}`DATABASE_TOKEN`{{% /code-placeholder-key %}}: + a [database token](/influxdb/cloud-dedicated/admin/tokens/) with _write_ permission to the database {{% /expand %}} @@ -212,14 +312,9 @@ Use the InfluxDB v2 or v1 API to write the NOAA Bay Area weather sample data to {{% code-placeholders "DATABASE_TOKEN|DATABASE_NAME" %}} ```sh -export INFLUX_HOST=http://cluster-id.influxdb.io -export INFLUX_TOKEN=DATABASE_TOKEN - -INFLUX_DATABASE=DATABASE_NAME - curl --request POST \ - "$INFLUX_HOST/api/v2/write?bucket=$INFLUX_DATABASE" \ - --header "Authorization: Bearer $INFLUX_TOKEN" \ + http://cluster-id.influxdb.io/api/v2/write?bucket=DATABASE_NAME \ + --header "Authorization: Bearer DATABASE_TOKEN" \ --header "Content-Type: text/plain; charset=utf-8" \ --header "Accept: application/json" \ --data-binary "$(curl --request GET https://docs.influxdata.com/downloads/bay-area-weather.lp)" @@ -231,14 +326,9 @@ curl --request POST \ {{% code-placeholders "DATABASE_TOKEN|DATABASE_NAME" %}} ```sh -export INFLUX_HOST=http://cluster-id.influxdb.io -export INFLUX_TOKEN=DATABASE_TOKEN - -INFLUX_DATABASE=DATABASE_NAME - curl --request POST \ - "$INFLUX_HOST/write?db=$INFLUX_DATABASE" \ - --header "Authorization: Bearer $INFLUX_TOKEN" \ + http://cluster-id.influxdb.io/write?db=DATABASE_NAME \ + --header "Authorization: Bearer DATABASE_TOKEN" \ --header "Content-type: text/plain; charset=utf-8" \ --data-binary "$(curl --request GET https://docs.influxdata.com/downloads/bay-area-weather.lp)" ``` @@ -247,10 +337,12 @@ curl --request POST \ {{% /code-tab-content %}} {{< /code-tabs-wrapper >}} -Replace the following in the script above: +Replace the following in the sample script: -- `DATABASE_NAME`: your InfluxDB Cloud Dedicated database -- `DATABASE_TOKEN`: a [database token](/influxdb/cloud-dedicated/admin/tokens/) +- {{% code-placeholder-key %}}`DATABASE_NAME`{{% /code-placeholder-key %}}: + your InfluxDB Cloud Dedicated database +- {{% code-placeholder-key %}}`DATABASE_TOKEN`{{% /code-placeholder-key %}}: + a [database token](/influxdb/cloud-dedicated/admin/tokens/) with sufficient permissions to the database {{% /expand %}} @@ -303,14 +395,9 @@ Use the InfluxDB v2 or v1 API to write the Bitcoin price sample data to {{% code-placeholders "DATABASE_TOKEN|DATABASE_NAME" %}} ```sh -export INFLUX_HOST=https://cluster-id.influxdb.io -export INFLUX_TOKEN=DATABASE_TOKEN - -INFLUX_DATABASE=DATABASE_NAME - curl --request POST \ - "$INFLUX_HOST/api/v2/write?bucket=$INFLUX_DATABASE" \ - --header "Authorization: Bearer $INFLUX_TOKEN" \ + http://cluster-id.influxdb.io/api/v2/write?bucket=DATABASE_NAME \ + --header "Authorization: Bearer DATABASE_TOKEN" \ --header "Content-Type: text/plain; charset=utf-8" \ --header "Accept: application/json" \ --data-binary "$(curl --request GET https://docs.influxdata.com/downloads/bitcoin.lp)" @@ -322,14 +409,9 @@ curl --request POST \ {{% code-placeholders "DATABASE_TOKEN|DATABASE_NAME" %}} ```sh -export INFLUX_HOST=https://cluster-id.influxdb.io -export INFLUX_TOKEN=DATABASE_TOKEN - -INFLUX_DATABASE=DATABASE_NAME - curl --request POST \ - "$INFLUX_HOST/write?db=$INFLUX_DATABASE" \ - --header "Authorization: Bearer $INFLUX_TOKEN" \ + http://cluster-id.influxdb.io/write?db=DATABASE_NAME \ + --header "Authorization: Bearer DATABASE_TOKEN" \ --header "Content-type: text/plain; charset=utf-8" \ --data-binary "$(curl --request GET https://docs.influxdata.com/downloads/bitcoin.lp)" ``` @@ -338,10 +420,12 @@ curl --request POST \ {{% /code-tab-content %}} {{< /code-tabs-wrapper >}} -Replace the following in the script above: +Replace the following in the sample script: -- `DATABASE_NAME`: your InfluxDB Cloud Dedicated database -- `DATABASE_TOKEN`: a [database token](/influxdb/cloud-dedicated/admin/tokens/) +- {{% code-placeholder-key %}}`DATABASE_NAME`{{% /code-placeholder-key %}}: + your InfluxDB Cloud Dedicated database +- {{% code-placeholder-key %}}`DATABASE_TOKEN`{{% /code-placeholder-key %}}: + a [database token](/influxdb/cloud-dedicated/admin/tokens/) with sufficient permissions to the database {{% /expand %}} @@ -382,14 +466,9 @@ Use the InfluxDB v2 or v1 API to write the random number sample data to {{% code-placeholders "DATABASE_TOKEN|DATABASE_NAME" %}} ```sh -export INFLUX_HOST=http://cluster-id.influxdb.io -export INFLUX_TOKEN=DATABASE_TOKEN - -INFLUX_DATABASE=DATABASE_NAME - curl --request POST \ - "$INFLUX_HOST/api/v2/write?bucket=$INFLUX_DATABASE" \ - --header "Authorization: Bearer $INFLUX_TOKEN" \ + http://cluster-id.influxdb.io/api/v2/write?bucket=DATABASE_NAME \ + --header "Authorization: Bearer DATABASE_TOKEN" \ --header "Content-Type: text/plain; charset=utf-8" \ --header "Accept: application/json" \ --data-binary "$(curl --request GET https://docs.influxdata.com/downloads/random-numbers.lp)" @@ -401,14 +480,9 @@ curl --request POST \ {{% code-placeholders "DATABASE_TOKEN|DATABASE_NAME" %}} ```sh -export INFLUX_HOST=http://cluster-id.influxdb.io -export INFLUX_TOKEN=DATABASE_TOKEN - -INFLUX_DATABASE=DATABASE_NAME - curl --request POST \ - "$INFLUX_HOST/write?db=$INFLUX_DATABASE" \ - --header "Authorization: Bearer $INFLUX_TOKEN" \ + http://cluster-id.influxdb.io/write?db=DATABASE_NAME \ + --header "Authorization: Bearer DATABASE_TOKEN" \ --header "Content-type: text/plain; charset=utf-8" \ --data-binary "$(curl --request GET https://docs.influxdata.com/downloads/random-numbers.lp)" ``` @@ -417,10 +491,12 @@ curl --request POST \ {{% /code-tab-content %}} {{< /code-tabs-wrapper >}} -Replace the following in the script above: +Replace the following in the sample script: -- `DATABASE_NAME`: your InfluxDB Cloud Dedicated database -- `DATABASE_TOKEN`: a [database token](/influxdb/cloud-dedicated/admin/tokens/) +- {{% code-placeholder-key %}}`DATABASE_NAME`{{% /code-placeholder-key %}}: + your InfluxDB Cloud Dedicated database +- {{% code-placeholder-key %}}`DATABASE_TOKEN`{{% /code-placeholder-key %}}: + a [database token](/influxdb/cloud-dedicated/admin/tokens/) with sufficient permissions to the database {{% /expand %}} diff --git a/content/influxdb/cloud-dedicated/reference/sql/_index.md b/content/influxdb/cloud-dedicated/reference/sql/_index.md index 999f384d0..5e1e8df0e 100644 --- a/content/influxdb/cloud-dedicated/reference/sql/_index.md +++ b/content/influxdb/cloud-dedicated/reference/sql/_index.md @@ -172,39 +172,40 @@ Comparison operators evaluate the relationship between the left and right operan The following reserved keywords cannot be used as identifiers. ```sql -AND -ALL -ANALYZE -AS -ASC +AND +ALL +ANALYZE +AS +ASC BETWEEN -BOTTOM +BOTTOM CASE -DESC -DISTINCT -EXISTS -EXPLAIN -FROM -GROUP BY -HAVING -IN -INNER JOIN -JOIN +DESC +DISTINCT +EXISTS +EXPLAIN +FROM +GROUP BY +HAVING +IN +INNER JOIN +JOIN LEFT JOIN -LIMIT -NOT EXISTS -NOT IN -OR -ORDER BY -FULL OUTER JOIN -RIGHT JOIN -SELECT -TOP -TYPE -UNION +LIMIT +NOT +EXISTS +NOT IN +OR +ORDER BY +FULL OUTER JOIN +RIGHT JOIN +SELECT +TOP +TYPE +UNION UNION ALL -WHERE -WITH +WHERE +WITH ``` ## Conditional expressions diff --git a/content/influxdb/cloud-dedicated/reference/sql/having.md b/content/influxdb/cloud-dedicated/reference/sql/having.md index fe7363fff..b6c86e0c9 100644 --- a/content/influxdb/cloud-dedicated/reference/sql/having.md +++ b/content/influxdb/cloud-dedicated/reference/sql/having.md @@ -8,6 +8,8 @@ menu: name: HAVING clause parent: SQL reference weight: 205 +related: + - /influxdb/cloud-dedicated/reference/sql/subqueries/ --- The `HAVING` clause places conditions on results created by an aggregate operation on groups. diff --git a/content/influxdb/cloud-dedicated/reference/sql/select.md b/content/influxdb/cloud-dedicated/reference/sql/select.md index b1df1eef7..bc404d749 100644 --- a/content/influxdb/cloud-dedicated/reference/sql/select.md +++ b/content/influxdb/cloud-dedicated/reference/sql/select.md @@ -7,6 +7,8 @@ menu: name: SELECT statement parent: SQL reference weight: 201 +related: + - /influxdb/cloud-dedicated/reference/sql/subqueries/ --- Use the `SELECT` statement to query data from an InfluxDB measurement. diff --git a/content/influxdb/cloud-dedicated/reference/sql/subqueries.md b/content/influxdb/cloud-dedicated/reference/sql/subqueries.md new file mode 100644 index 000000000..cb3379e6a --- /dev/null +++ b/content/influxdb/cloud-dedicated/reference/sql/subqueries.md @@ -0,0 +1,757 @@ +--- +title: Subqueries +description: > + Subqueries (also known as inner queries or nested queries) are queries within + a query. Subqueries can be used in `SELECT`, `FROM`, `WHERE`, and `HAVING` clauses. +menu: + influxdb_cloud_dedicated: + name: Subqueries + parent: SQL reference +weight: 210 +related: + - /influxdb/cloud-dedicated/query-data/sql/ + - /influxdb/cloud-dedicated/reference/sql/select/ + - /influxdb/cloud-dedicated/reference/sql/where/ + - /influxdb/cloud-dedicated/reference/sql/having/ +--- + +Subqueries (also known as inner queries or nested queries) are queries within +a query. +Subqueries can be used in `SELECT`, `FROM`, `WHERE`, and `HAVING` clauses. + +- [Subquery operators](#subquery-operators) + - [[ NOT ] EXISTS](#-not--exists) + - [[ NOT ] IN](#-not--in) +- [SELECT clause subqueries](#select-clause-subqueries) +- [FROM clause subqueries](#from-clause-subqueries) +- [WHERE clause subqueries](#where-clause-subqueries) +- [HAVING clause subqueries](#having-clause-subqueries) +- [Subquery categories](#subquery-categories) + - [Correlated subqueries](#correlated-subqueries) + - [Non-correlated subqueries](#non-correlated-subqueries) + - [Scalar subqueries](#scalar-subqueries) + - [Non-scalar subqueries](#non-scalar-subqueries) + +{{% note %}} +#### Sample data + +Query examples on this page use the following sample data sets: + +- [Get started home sensor sample data](/influxdb/cloud-dedicated/reference/sample-data/#get-started-home-sensor-data) +- [Home sensor actions sample data](/influxdb/cloud-dedicated/reference/sample-data/#home-sensor-actions-data) +- [NOAA Bay Area weather sample data](/influxdb/cloud-serverless/reference/sample-data/#noaa-bay-area-weather-data) + +{{% /note %}} + +## Subquery operators + +- [[ NOT ] EXISTS](#-not--exists) +- [[ NOT ] IN](#-not--in) + +### [ NOT ] EXISTS + +The `EXISTS` operator returns all rows where a +_[correlated subquery](#correlated-subquery)_ produces one or more matches for +that row. `NOT EXISTS` returns all rows where a _correlated subquery_ produces +zero matches for that row. Only _correlated subqueries_ are supported. + +#### Syntax {#-not-exists-syntax} + +```sql +[NOT] EXISTS (subquery) +``` + +### [ NOT ] IN + +The `IN` operator returns all rows where a given expression’s value can be found +in the results of a _[correlated subquery](#correlated-subqueries)_. +`NOT IN` returns all rows where a given expression’s value cannot be found in +the results of a subquery or list of values. + +#### Syntax {#-not-in-syntax} + +```sql +expression [NOT] IN (subquery|list-literal) +``` + +#### Examples {#-not-in-examples} + +{{< expand-wrapper >}} +{{% expand "View `IN` examples using a query" %}} +{{< code-tabs-wrapper >}} +{{% code-tabs %}} +[IN](#) +[NOT IN](#) +{{% /code-tabs %}} +{{% code-tab-content %}} +```sql +SELECT + time, + room, + temp +FROM + home +WHERE + room IN ( + SELECT + DISTINCT room + FROM + home_actions + ) +``` +{{% /code-tab-content %}} +{{% code-tab-content %}} +```sql +SELECT + time, + room, + temp +FROM + home +WHERE + room NOT IN ( + SELECT + DISTINCT room + FROM + home_actions + ) +``` +{{% /code-tab-content %}} +{{< /code-tabs-wrapper >}} +{{% /expand %}} + +{{% expand "View `IN` examples using a list literal" %}} +{{< code-tabs-wrapper >}} +{{% code-tabs %}} +[IN](#) +[NOT IN](#) +{{% /code-tabs %}} +{{% code-tab-content %}} +```sql +SELECT + time, + room, + temp +FROM home +WHERE room IN ('Bathroom', 'Bedroom', 'Kitchen') +``` +{{% /code-tab-content %}} +{{% code-tab-content %}} +```sql +SELECT + time, + room, + temp +FROM home +WHERE room NOT IN ('Bathroom', 'Bedroom', 'Kitchen') +``` +{{% /code-tab-content %}} +{{< /code-tabs-wrapper >}} +{{% /expand %}} + +{{< /expand-wrapper >}} + +## SELECT clause subqueries + +`SELECT` clause subqueries use values returned from inner query as part +of the outer query's `SELECT` list. +The `SELECT` clause only supports [scalar subqueries](#scalar-subqueries) that +return a single value per execution of the inner query. +The returned value can be unique per row. + +### Syntax {#select-subquery-syntax} + +```sql +SELECT [expression1[, expression2, ..., expressionN],] () +``` + +{{% note %}} +`SELECT` clause subqueries can be used as an alternative to `JOIN` operations. +{{% /note %}} + +### Examples {#select-subquery-examples} + +{{< expand-wrapper >}} +{{% expand "`SELECT` clause with correlated subquery" %}} + +```sql +SELECT + time, + room, + co, + ( + SELECT + MAX(description) + FROM + home_actions + WHERE + time = home.time + AND room = home.room + AND level != 'ok' + ) AS "Alert Description" +FROM + home +ORDER BY + room, + time +``` + +#### Inner query results + +Because the inner query is a [correlated subquery](#correlated-subqueries), +the result depends on the values of `room` and `time` columns in the outer query. +The results below represent the action description for each `room` and `time` +combination with a `level` value that does not equal `ok`. + +{{% influxdb/custom-timestamps %}} +| time | room | MAX(home_actions.description) | +| :------------------- | :---------- | :------------------------------------------ | +| 2022-01-01T18:00:00Z | Kitchen | Carbon monoxide level above normal: 18 ppm. | +| 2022-01-01T19:00:00Z | Kitchen | Carbon monoxide level above normal: 22 ppm. | +| 2022-01-01T20:00:00Z | Kitchen | Carbon monoxide level above normal: 26 ppm. | +| 2022-01-01T19:00:00Z | Living Room | Carbon monoxide level above normal: 14 ppm. | +| 2022-01-01T20:00:00Z | Living Room | Carbon monoxide level above normal: 17 ppm. | +{{% /influxdb/custom-timestamps %}} + +#### Outer query results + +{{% influxdb/custom-timestamps %}} +| time | room | co | Alert Description | +| :------------------- | :---------- | --: | :------------------------------------------ | +| 2022-01-01T08:00:00Z | Kitchen | 0 | | +| 2022-01-01T09:00:00Z | Kitchen | 0 | | +| 2022-01-01T10:00:00Z | Kitchen | 0 | | +| 2022-01-01T11:00:00Z | Kitchen | 0 | | +| 2022-01-01T12:00:00Z | Kitchen | 0 | | +| 2022-01-01T13:00:00Z | Kitchen | 1 | | +| 2022-01-01T14:00:00Z | Kitchen | 1 | | +| 2022-01-01T15:00:00Z | Kitchen | 3 | | +| 2022-01-01T16:00:00Z | Kitchen | 7 | | +| 2022-01-01T17:00:00Z | Kitchen | 9 | | +| 2022-01-01T18:00:00Z | Kitchen | 18 | Carbon monoxide level above normal: 18 ppm. | +| 2022-01-01T19:00:00Z | Kitchen | 22 | Carbon monoxide level above normal: 22 ppm. | +| 2022-01-01T20:00:00Z | Kitchen | 26 | Carbon monoxide level above normal: 26 ppm. | +| 2022-01-01T08:00:00Z | Living Room | 0 | | +| 2022-01-01T09:00:00Z | Living Room | 0 | | +| 2022-01-01T10:00:00Z | Living Room | 0 | | +| 2022-01-01T11:00:00Z | Living Room | 0 | | +| 2022-01-01T12:00:00Z | Living Room | 0 | | +| 2022-01-01T13:00:00Z | Living Room | 0 | | +| 2022-01-01T14:00:00Z | Living Room | 0 | | +| 2022-01-01T15:00:00Z | Living Room | 1 | | +| 2022-01-01T16:00:00Z | Living Room | 4 | | +| 2022-01-01T17:00:00Z | Living Room | 5 | | +| 2022-01-01T18:00:00Z | Living Room | 9 | | +| 2022-01-01T19:00:00Z | Living Room | 14 | Carbon monoxide level above normal: 14 ppm. | +| 2022-01-01T20:00:00Z | Living Room | 17 | Carbon monoxide level above normal: 17 ppm. | +{{% /influxdb/custom-timestamps %}} + +{{% /expand %}} +{{< /expand-wrapper >}} + +## FROM clause subqueries + +`FROM` clause subqueries return a set of results that is then queried and +operated on by the outer query. + +### Syntax {#from-subquery-syntax} + +```sql +SELECT expression1[, expression2, ..., expressionN] FROM () +``` + +### Examples {#from-subquery-examples} + +{{< expand-wrapper >}} +{{% expand "View `FROM` clause subquery example" %}} + +The following query returns the average of maximum values per room. +The inner query returns the maximum value for each field from each room. +The outer query uses the results of the inner query and returns the average +maximum value for each field. + +```sql +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 + ) +``` + +#### Inner query results + +| room | max_co | max_hum | max_temp | +| :---------- | -----: | ------: | -------: | +| Living Room | 17 | 36.4 | 22.8 | +| Kitchen | 26 | 36.9 | 23.3 | + +#### Outer query results + +| avg_max_co | avg_max_hum | avg_max_temp | +| ---------: | ----------: | -----------: | +| 21.5 | 36.7 | 23.1 | + +{{% /expand %}} +{{< /expand-wrapper >}} + +## WHERE clause subqueries + +[`WHERE` clause](/influxdb/cloud-dedicated/reference/sql/where/) subqueries +compare an expression to the result of the subquery and return _true_ or _false_. +Rows that evaluate to _false_ are filtered from results. +The `WHERE` clause supports correlated and non-correlated subqueries +as well as scalar and non-scalar subqueries (depending on the the operator used +in the predicate expression). + +### Syntax {#where-subquery-syntax} + +```sql +SELECT + expression1[, expression2, ..., expressionN] +FROM + +WHERE + expression operator () +``` + +{{% note %}} +`WHERE` clause subqueries can be used as an alternative to `JOIN` operations. +{{% /note %}} + +### Examples {#where-subquery-examples} +{{< expand-wrapper >}} +{{% expand "`WHERE` clause with scalar subquery" %}} + +The following query returns all points with `temp` values above the average +of all `temp` values. The subquery returns the average `temp` value. + +```sql +SELECT + * +FROM + home +WHERE + temp > ( + SELECT + AVG(temp) + FROM + home + ) +``` + +#### Inner query result + +| AVG(home.temp) | +| :----------------- | +| 22.396153846153844 | + +#### Outer query result + +{{% influxdb/custom-timestamps %}} +| 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 | +{{% /influxdb/custom-timestamps %}} + +{{% /expand %}} +{{% expand "`WHERE` clause with non-scalar subquery" %}} + +Non-scalar subqueries must use the `[NOT] IN` operator and can only return a +single column. The values in the returned column are evaluated as a list. + +The following query returns all points in the `home` measurement associated with +the same timestamps as `warn` level alerts in the `home_actions` measurement. + +```sql +SELECT + * +FROM + home +WHERE + time IN ( + SELECT + DISTINCT time + FROM + home_actions + WHERE + level = 'warn' + ) +``` + +#### Inner query result + +{{% influxdb/custom-timestamps %}} +| time | +| :------------------- | +| 2022-01-01T18:00:00Z | +| 2022-01-01T19:00:00Z | +| 2022-01-01T20:00:00Z | +{{% /influxdb/custom-timestamps %}} + +#### Outer query result + +{{% influxdb/custom-timestamps %}} +| 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 | +{{% /influxdb/custom-timestamps %}} + +{{% /expand %}} +{{% expand "`WHERE` clause with correlated subquery" %}} + +The following query returns rows with temperature values greater than the median +temperature value for each room. The subquery in the `WHERE` clause uses the +`room` value from the outer query to return the median `temp` value for that +specific room. + +```sql +SELECT + time, + room, + temp +FROM + home outer_query +WHERE + temp > ( + SELECT + median(temp) AS temp + FROM + home + WHERE + room = outer_query.room + GROUP BY + room + ) +ORDER BY room, time +``` + +#### Inner query result + +The result of the inner query depends on the value of `room` in the outer query, +but the following table contains the median `temp` value for each room. + +| room | temp | +| :---------- | ---: | +| Living Room | 22.3 | +| Kitchen | 22.7 | + +#### Outer query result + +{{% influxdb/custom-timestamps %}} +| time | room | temp | +| :------------------- | :---------- | ---: | +| 2022-01-01T09:00:00Z | Kitchen | 23 | +| 2022-01-01T13:00:00Z | Kitchen | 22.8 | +| 2022-01-01T14:00:00Z | Kitchen | 22.8 | +| 2022-01-01T18:00:00Z | Kitchen | 23.3 | +| 2022-01-01T19:00:00Z | Kitchen | 23.1 | +| 2022-01-01T13:00:00Z | Living Room | 22.4 | +| 2022-01-01T16:00:00Z | Living Room | 22.4 | +| 2022-01-01T17:00:00Z | Living Room | 22.6 | +| 2022-01-01T18:00:00Z | Living Room | 22.8 | +| 2022-01-01T19:00:00Z | Living Room | 22.5 | +{{% /influxdb/custom-timestamps %}} + +{{% /expand %}} +{{< /expand-wrapper >}} + +## HAVING clause subqueries + +[`HAVING` clause](/influxdb/cloud-dedicated/reference/sql/having/) subqueries +compare an expression that uses aggregate values returned by aggregate functions +in the `SELECT` clause to the result of the subquery and return _true_ or _false_. +Rows that evaluate to _false_ are filtered from results. +The `HAVING` clause supports correlated and non-correlated subqueries +as well as scalar and non-scalar subqueries (depending on the the operator used +in the predicate expression). + +### Syntax {#having-subquery-syntax} + +```sql +SELECT + aggregate_expression1[, aggregate_expression2, ..., aggregate_expressionN] +FROM + +WHERE + +GROUP BY + column_expression1[, column_expression2, ..., column_expressionN] +HAVING + expression operator () +``` + +### Examples {#having-subquery-examples} + +{{< expand-wrapper >}} +{{% expand "`HAVING` clause with scalar subquery" %}} + +The following query returns all two hour blocks of time with average `temp` values +greater then the median `temp` value. + +```sql +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 + ) +``` + +#### Inner query result + +| MEDIAN(home.temp) | +| :---------------- | +| 22.45 | + +#### Outer query result + +{{% influxdb/custom-timestamps %}} +| 2-hour block | 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 | +{{% /influxdb/custom-timestamps %}} + +{{% /expand %}} +{{% expand "`HAVING` clause with non-scalar subquery" %}} + +Non-scalar subqueries must use the `[NOT] IN` operator and can only return a +single column. The values in the returned column are evaluated as a list. + +The following query returns the maximum `co` and `temp` values within 2-hour +windows of time where the `time` value associated with time window is also +associated with a warning in the `home_actions` measurement. + +```sql +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' + ) +``` + +#### Inner query result + +{{% influxdb/custom-timestamps %}} +| time | +| :------------------- | +| 2022-01-01T18:00:00Z | +| 2022-01-01T19:00:00Z | +| 2022-01-01T20:00:00Z | +{{% /influxdb/custom-timestamps %}} + +#### Outer query result + +{{% influxdb/custom-timestamps %}} +| 2-hour block | 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 | +{{% /influxdb/custom-timestamps %}} + +{{% /expand %}} +{{% expand "`HAVING` clause with correlated subquery" %}} + +The following query returns 2-hour windows of time with average `temp` values +greater than the median `temp` value for each room. The subquery in the `HAVING` +clause uses the `room` value from the outer query to return the median `temp` value +for that specific room. + +```sql +SELECT + time, + room, + temp +FROM + home outer_query +WHERE + temp > ( + SELECT + median(temp) AS temp + FROM + home + WHERE + room = outer_query.room + GROUP BY + room + ) +ORDER BY room, time +``` + +#### Inner query result + +The result of the inner query depends on the value of `room` in the outer query, +but the following table contains the median `temp` value for each room. + +| room | temp | +| :---------- | ---: | +| Living Room | 22.3 | +| Kitchen | 22.7 | + +#### Outer query result + +{{% influxdb/custom-timestamps %}} +| 2-hour block | room | avg_temp | +| :------------------- | :---------- | -----------------: | +| 2022-01-01T14:00:00Z | Kitchen | 22.75 | +| 2022-01-01T18:00:00Z | Kitchen | 23.200000000000003 | +| 2022-01-01T16:00:00Z | Living Room | 22.5 | +| 2022-01-01T18:00:00Z | Living Room | 22.65 | +{{% /influxdb/custom-timestamps %}} + +{{% /expand %}} +{{< /expand-wrapper >}} + +## Subquery categories + +SQL subqueries can be categorized as one or more of the following base on the +behavior of the subquery: + +- [correlated](#correlated-subqueries) or [non-correlated](#non-correlated-subqueries) +- [scalar](#scalar-subqueries) or [non-scalar](#non-scalar-subqueries) + +### Correlated subqueries + +In a **correlated** subquery, the inner query depends on the outer query, using +values from the outer query for its results. +Correlated subqueries can return a maximum of one row, so +[aggregations](/influxdb/cloud-dedicated/reference/sql/functions/aggregate/) may +be required in the inner query. + +In the query below, the inner query (`SELECT temp_avg FROM weather WHERE location = home.room`) +depends on data (`home.room`) from the outer query +(`SELECT time, room, temp FROM home`) and is therefore a _correlated_ subquery. + +```sql +SELECT + time, + room, + temp +FROM + home +WHERE + temp = ( + SELECT + temp_avg + FROM + weather + WHERE + location = home.room + ) +``` + +{{% note %}} +#### Correlated subquery performance + +Because correlated subqueries depend on the outer query and typically must +execute for each row returned by the outer query, correlated subqueries are +**less performant** than non-correlated subqueries. +{{% /note %}} + +### Non-correlated subqueries + +In a **non-correlated** subquery, the inner query _doesn't_ depend on the outer +query and executes independently. +The inner query executes first, and then passes the results to the outer query. + +In the query below, the inner query (`SELECT MIN(temp_avg) FROM weather`) can +run independently from the outer query (`SELECT time, temp FROM home`) and is +therefore a _non-correlated_ subquery. + +```sql +SELECT + time, + temp +FROM + home +WHERE + temp < ( + SELECT + MIN(temp_avg) + FROM + weather + ) +``` + +### Scalar subqueries + +A **scalar** subquery returns a single value (one column of one row). +If no rows are returned, the subquery returns NULL. + +The example subquery below returns the average value of a specified column. +This value is a single scalar value. + +```sql +SELECT * FROM home WHERE co > (SELECT avg(co) FROM home) +``` + +### Non-scalar subqueries + +A **non-scalar** subquery returns 0, 1, or multiple rows, each of which may +contain 1 or multiple columns. For each column, if there is no value to return, +the subquery returns NULL. If no rows qualify to be returned, the subquery +returns 0 rows. + +The example subquery below returns all distinct values in a column. +Multiple values are returned. + +```sql +SELECT * FROM home WHERE room IN (SELECT DISTINCT room FROM home_actions) +``` \ No newline at end of file diff --git a/content/influxdb/cloud-dedicated/reference/sql/where.md b/content/influxdb/cloud-dedicated/reference/sql/where.md index 121397769..d0801b86c 100644 --- a/content/influxdb/cloud-dedicated/reference/sql/where.md +++ b/content/influxdb/cloud-dedicated/reference/sql/where.md @@ -8,6 +8,8 @@ menu: name: WHERE clause parent: SQL reference weight: 202 +related: + - /influxdb/cloud-dedicated/reference/sql/subqueries/ --- Use the `WHERE` clause to filter results based on fields, tags, or timestamps. diff --git a/content/influxdb/cloud-serverless/reference/sample-data.md b/content/influxdb/cloud-serverless/reference/sample-data.md index 74e3544cd..786f8d805 100644 --- a/content/influxdb/cloud-serverless/reference/sample-data.md +++ b/content/influxdb/cloud-serverless/reference/sample-data.md @@ -1,7 +1,7 @@ --- title: Sample data description: > - Sample datasets are used throughout the the InfluxDB Cloud Dedicated + Sample datasets are used throughout the the InfluxDB Cloud Serverless documentation to demonstrate functionality. Use the following sample datasets to replicate provided examples. menu: @@ -16,6 +16,7 @@ demonstrate functionality. Use the following sample datasets to replicate provided examples. - [Get started home sensor data](#get-started-home-sensor-data) +- [Home sensor actions data](#home-sensor-actions-data) - [NOAA Bay Area weather data](#noaa-bay-area-weather-data) - [Bitcoin price data](#bitcoin-price-data) - [Random numbers sample data](#random-numbers-sample-data) @@ -68,14 +69,9 @@ to {{< cloud-name >}}. {{% influxdb/custom-timestamps %}} {{% code-placeholders "API_TOKEN|BUCKET_NAME" "magenta" %}} ```sh -export INFLUX_HOST=https://cloud2.influxdata.com -export INFLUX_TOKEN=API_TOKEN - -INFLUX_BUCKET=BUCKET_NAME - curl --request POST \ - "$INFLUX_HOST/api/v2/write?bucket=$INFLUX_BUCKET&precision=s" \ - --header "Authorization: Bearer $INFLUX_TOKEN" \ + https://cloud2.influxdata.com/api/v2/write?bucket=BUCKET_NAME&precision=s \ + --header "Authorization: Bearer API_TOKEN" \ --header "Content-Type: text/plain; charset=utf-8" \ --header "Accept: application/json" \ --data-binary " @@ -116,14 +112,9 @@ home,room=Kitchen temp=22.7,hum=36.5,co=26i 1641067200 {{% influxdb/custom-timestamps %}} {{% code-placeholders "API_TOKEN|BUCKET_NAME" "magenta" %}} ```sh -export INFLUX_HOST=https://cloud2.influxdata.com -export INFLUX_TOKEN=API_TOKEN - -INFLUX_BUCKET=BUCKET_NAME - curl --request POST \ - "$INFLUX_HOST/write?db=$INFLUX_BUCKET&precision=s" \ - --header "Authorization: Bearer $INFLUX_TOKEN" \ + https://cloud2.influxdata.com/write?db=BUCKET_NAME&precision=s \ + --header "Authorization: Bearer API_TOKEN" \ --header "Content-type: text/plain; charset=utf-8" \ --data-binary " home,room=Living\ Room temp=21.1,hum=35.9,co=0i 1641024000 @@ -160,7 +151,7 @@ home,room=Kitchen temp=22.7,hum=36.5,co=26i 1641067200 {{% /code-tab-content %}} {{< /code-tabs-wrapper >}} -Replace the following in the script above: +Replace the following in the sample script: - {{% code-placeholder-key %}}`BUCKET_NAME`{{% /code-placeholder-key %}}: your InfluxDB Cloud Serverless bucket @@ -171,6 +162,113 @@ Replace the following in the script above: {{% /expand %}} {{< /expand-wrapper >}} +## Home sensor actions data + +Includes hypothetical actions triggered by data in the [Get started home sensor data](#get-started-home-sensor-data) +and is a companion dataset to that sample dataset. +To customize timestamps in the dataset, use the {{< icon "clock" >}} button in +the lower right corner of the page. +This lets you modify the sample dataset to stay within the retention period of +the database you write it to. + +##### Time Range + +**{{% influxdb/custom-timestamps-span %}}2022-01-01T08:00:00Z{{% /influxdb/custom-timestamps-span %}}** +to +**{{% influxdb/custom-timestamps-span %}}2022-01-01T20:00:00Z{{% /influxdb/custom-timestamps-span %}}** +(Customizable) + +##### Schema + +- home_actions (measurement) + - **tags**: + - room + - Kitchen + - Living Room + - action + - alert + - cool + - level + - ok + - warn + - **fields**: + - description (string) + +{{< expand-wrapper >}} +{{% expand "Write home sensor actions data to InfluxDB" %}} + +#### Write the home sensor actions data to InfluxDB + +Use the InfluxDB v2 or v1 API to write the home sensor actions sample data +to {{< cloud-name >}}. + +{{< code-tabs-wrapper >}} +{{% code-tabs %}} +[v2 API](#) +[v1 API](#) +{{% /code-tabs %}} +{{% code-tab-content %}} + +{{% influxdb/custom-timestamps %}} +{{% code-placeholders "API_TOKEN|BUCKET_NAME" %}} +```sh +curl --request POST \ + https://cloud2.influxdata.com/api/v2/write?bucket=BUCKET_NAME&precision=s \ + --header "Authorization: Bearer API_TOKEN" \ + --header "Content-Type: text/plain; charset=utf-8" \ + --header "Accept: application/json" \ + --data-binary ' +home_actions,room=Kitchen,action=cool,level=ok description="Temperature at or above 23°C (23°C). Cooling to 22°C." 1641027600 +home_actions,room=Kitchen,action=cool,level=ok description="Temperature at or above 23°C (23.3°C). Cooling to 22°C." 1641060000 +home_actions,room=Kitchen,action=cool,level=ok description="Temperature at or above 23°C (23.1°C). Cooling to 22°C." 1641063600 +home_actions,room=Kitchen,action=alert,level=warn description="Carbon monoxide level above normal: 18 ppm." 1641060000 +home_actions,room=Kitchen,action=alert,level=warn description="Carbon monoxide level above normal: 22 ppm." 1641063600 +home_actions,room=Kitchen,action=alert,level=warn description="Carbon monoxide level above normal: 26 ppm." 1641067200 +home_actions,room=Living\ Room,action=alert,level=warn description="Carbon monoxide level above normal: 14 ppm." 1641063600 +home_actions,room=Living\ Room,action=alert,level=warn description="Carbon monoxide level above normal: 17 ppm." 1641067200 +' +``` +{{% /code-placeholders %}} +{{% /influxdb/custom-timestamps %}} + +{{% /code-tab-content %}} +{{% code-tab-content %}} + +{{% influxdb/custom-timestamps %}} +{{% code-placeholders "API_TOKEN|BUCKET_NAME" %}} +```sh +curl --request POST \ + https://cloud2.influxdata.com/write?db=BUCKET_NAME&precision=s \ + --header "Authorization: Bearer API_TOKEN" \ + --header "Content-type: text/plain; charset=utf-8" \ + --data-binary ' +home_actions,room=Kitchen,action=cool,level=ok description="Temperature at or above 23°C (23°C). Cooling to 22°C." 1641027600 +home_actions,room=Kitchen,action=cool,level=ok description="Temperature at or above 23°C (23.3°C). Cooling to 22°C." 1641060000 +home_actions,room=Kitchen,action=cool,level=ok description="Temperature at or above 23°C (23.1°C). Cooling to 22°C." 1641063600 +home_actions,room=Kitchen,action=alert,level=warn description="Carbon monoxide level above normal: 18 ppm." 1641060000 +home_actions,room=Kitchen,action=alert,level=warn description="Carbon monoxide level above normal: 22 ppm." 1641063600 +home_actions,room=Kitchen,action=alert,level=warn description="Carbon monoxide level above normal: 26 ppm." 1641067200 +home_actions,room=Living\ Room,action=alert,level=warn description="Carbon monoxide level above normal: 14 ppm." 1641063600 +home_actions,room=Living\ Room,action=alert,level=warn description="Carbon monoxide level above normal: 17 ppm." 1641067200 +' +``` +{{% /code-placeholders %}} +{{% /influxdb/custom-timestamps %}} + +{{% /code-tab-content %}} +{{< /code-tabs-wrapper >}} + +Replace the following in the sample script: + +- {{% code-placeholder-key %}}`BUCKET_NAME`{{% /code-placeholder-key %}}: + your InfluxDB Cloud Serverless bucket +- {{% code-placeholder-key %}}`API_TOKEN`{{% /code-placeholder-key %}}: + a [database token](/influxdb/cloud-serverless/admin/tokens/) + with _write_ permission to the database + +{{% /expand %}} +{{< /expand-wrapper >}} + ## NOAA Bay Area weather data Includes daily weather metrics from three San Francisco Bay Area airports from @@ -214,14 +312,9 @@ Use the InfluxDB v2 or v1 API to write the NOAA Bay Area weather sample data to {{% code-placeholders "API_TOKEN|BUCKET_NAME" %}} ```sh -export INFLUX_HOST=https://cloud2.influxdata.com -export INFLUX_TOKEN=API_TOKEN - -INFLUX_BUCKET=BUCKET_NAME - curl --request POST \ - "$INFLUX_HOST/api/v2/write?bucket=$INFLUX_BUCKET" \ - --header "Authorization: Bearer $INFLUX_TOKEN" \ + https://cloud2.influxdata.com/api/v2/write?bucket=BUCKET_NAME \ + --header "Authorization: Bearer API_TOKEN" \ --header "Content-Type: text/plain; charset=utf-8" \ --header "Accept: application/json" \ --data-binary "$(curl --request GET https://docs.influxdata.com/downloads/bay-area-weather.lp)" @@ -233,14 +326,9 @@ curl --request POST \ {{% code-placeholders "API_TOKEN|BUCKET_NAME" "magenta" %}} ```sh -export INFLUX_HOST=https://cloud2.influxdata.com -export INFLUX_TOKEN=API_TOKEN - -INFLUX_BUCKET=BUCKET_NAME - curl --request POST \ - "$INFLUX_HOST/write?db=$INFLUX_BUCKET" \ - --header "Authorization: Bearer $INFLUX_TOKEN" \ + https://cloud2.influxdata.com/write?db=BUCKET_NAME \ + --header "Authorization: Bearer API_TOKEN" \ --header "Content-type: text/plain; charset=utf-8" \ --data-binary "$(curl --request GET https://docs.influxdata.com/downloads/bay-area-weather.lp)" ``` @@ -249,7 +337,7 @@ curl --request POST \ {{% /code-tab-content %}} {{< /code-tabs-wrapper >}} -Replace the following in the script above: +Replace the following in the sample script: - {{% code-placeholder-key %}}`BUCKET_NAME`{{% /code-placeholder-key %}}: your InfluxDB Cloud Serverless bucket @@ -307,14 +395,9 @@ Use the InfluxDB v2 or v1 API to write the Bitcoin price sample data to {{% code-placeholders "API_TOKEN|BUCKET_NAME" "magenta" %}} ```sh -export INFLUX_HOST=https://cloud2.influxdata.com -export INFLUX_TOKEN=API_TOKEN - -INFLUX_BUCKET=BUCKET_NAME - curl --request POST \ - "$INFLUX_HOST/api/v2/write?bucket=$INFLUX_BUCKET" \ - --header "Authorization: Bearer $INFLUX_TOKEN" \ + https://cloud2.influxdata.com/api/v2/write?bucket=BUCKET_NAME \ + --header "Authorization: Bearer API_TOKEN" \ --header "Content-Type: text/plain; charset=utf-8" \ --header "Accept: application/json" \ --data-binary "$(curl --request GET https://docs.influxdata.com/downloads/bitcoin.lp)" @@ -326,14 +409,9 @@ curl --request POST \ {{% code-placeholders "API_TOKEN|BUCKET_NAME" "magenta" %}} ```sh -export INFLUX_HOST=https://cloud2.influxdata.com -export INFLUX_TOKEN=API_TOKEN - -INFLUX_BUCKET=BUCKET_NAME - curl --request POST \ - "$INFLUX_HOST/write?db=$INFLUX_BUCKET" \ - --header "Authorization: Bearer $INFLUX_TOKEN" \ + https://cloud2.influxdata.com/write?db=BUCKET_NAME \ + --header "Authorization: Bearer API_TOKEN" \ --header "Content-type: text/plain; charset=utf-8" \ --data-binary "$(curl --request GET https://docs.influxdata.com/downloads/bitcoin.lp)" ``` @@ -342,7 +420,7 @@ curl --request POST \ {{% /code-tab-content %}} {{< /code-tabs-wrapper >}} -Replace the following in the script above: +Replace the following in the sample script: - {{% code-placeholder-key %}}`BUCKET_NAME`{{% /code-placeholder-key %}}: your InfluxDB Cloud Serverless bucket @@ -388,14 +466,9 @@ Use the InfluxDB v2 or v1 API to write the random number sample data to {{% code-placeholders "API_TOKEN|BUCKET_NAME" "magenta" %}} ```sh -export INFLUX_HOST=https://cloud2.influxdata.com -export INFLUX_TOKEN=API_TOKEN - -INFLUX_BUCKET=BUCKET_NAME - curl --request POST \ - "$INFLUX_HOST/api/v2/write?bucket=$INFLUX_BUCKET" \ - --header "Authorization: Bearer $INFLUX_TOKEN" \ + https://cloud2.influxdata.com/api/v2/write?bucket=BUCKET_NAME \ + --header "Authorization: Bearer API_TOKEN" \ --header "Content-Type: text/plain; charset=utf-8" \ --header "Accept: application/json" \ --data-binary "$(curl --request GET https://docs.influxdata.com/downloads/random-numbers.lp)" @@ -407,14 +480,9 @@ curl --request POST \ {{% code-placeholders "API_TOKEN|BUCKET_NAME" "magenta" %}} ```sh -export INFLUX_HOST=https://cloud2.influxdata.com -export INFLUX_TOKEN=API_TOKEN - -INFLUX_BUCKET=BUCKET_NAME - curl --request POST \ - "$INFLUX_HOST/write?db=$INFLUX_BUCKET" \ - --header "Authorization: Bearer $INFLUX_TOKEN" \ + https://cloud2.influxdata.com/write?db=BUCKET_NAME \ + --header "Authorization: Bearer API_TOKEN" \ --header "Content-type: text/plain; charset=utf-8" \ --data-binary "$(curl --request GET https://docs.influxdata.com/downloads/random-numbers.lp)" ``` @@ -423,7 +491,7 @@ curl --request POST \ {{% /code-tab-content %}} {{< /code-tabs-wrapper >}} -Replace the following in the script above: +Replace the following in the sample script: - {{% code-placeholder-key %}}`BUCKET_NAME`{{% /code-placeholder-key %}}: your InfluxDB Cloud Serverless bucket diff --git a/content/influxdb/cloud-serverless/reference/sql/_index.md b/content/influxdb/cloud-serverless/reference/sql/_index.md index b4ae25cd7..4a5f40311 100644 --- a/content/influxdb/cloud-serverless/reference/sql/_index.md +++ b/content/influxdb/cloud-serverless/reference/sql/_index.md @@ -172,39 +172,40 @@ Comparison operators evaluate the relationship between the left and right operan The following reserved keywords cannot be used as identifiers. ```sql -AND -ALL -ANALYZE -AS -ASC +AND +ALL +ANALYZE +AS +ASC BETWEEN -BOTTOM +BOTTOM CASE -DESC -DISTINCT -EXISTS -EXPLAIN -FROM -GROUP BY -HAVING -IN -INNER JOIN -JOIN +DESC +DISTINCT +EXISTS +EXPLAIN +FROM +GROUP BY +HAVING +IN +INNER JOIN +JOIN LEFT JOIN -LIMIT -NOT EXISTS -NOT IN -OR -ORDER BY -FULL OUTER JOIN -RIGHT JOIN -SELECT -TOP -TYPE -UNION +LIMIT +NOT +EXISTS +NOT IN +OR +ORDER BY +FULL OUTER JOIN +RIGHT JOIN +SELECT +TOP +TYPE +UNION UNION ALL -WHERE -WITH +WHERE +WITH ``` ## Conditional expressions diff --git a/content/influxdb/cloud-serverless/reference/sql/having.md b/content/influxdb/cloud-serverless/reference/sql/having.md index 8981075af..f378fb0ea 100644 --- a/content/influxdb/cloud-serverless/reference/sql/having.md +++ b/content/influxdb/cloud-serverless/reference/sql/having.md @@ -8,6 +8,8 @@ menu: name: HAVING clause parent: SQL reference weight: 205 +related: + - /influxdb/cloud-serverless/reference/sql/subqueries/ --- The `HAVING` clause places conditions on results created by an aggregate operation on groups. diff --git a/content/influxdb/cloud-serverless/reference/sql/select.md b/content/influxdb/cloud-serverless/reference/sql/select.md index 5b1674e94..b173d27a6 100644 --- a/content/influxdb/cloud-serverless/reference/sql/select.md +++ b/content/influxdb/cloud-serverless/reference/sql/select.md @@ -7,6 +7,8 @@ menu: name: SELECT statement parent: SQL reference weight: 201 +related: + - /influxdb/cloud-serverless/reference/sql/subqueries/ --- Use the `SELECT` statement to query data from an InfluxDB measurement. diff --git a/content/influxdb/cloud-serverless/reference/sql/subqueries.md b/content/influxdb/cloud-serverless/reference/sql/subqueries.md new file mode 100644 index 000000000..bbe19294f --- /dev/null +++ b/content/influxdb/cloud-serverless/reference/sql/subqueries.md @@ -0,0 +1,757 @@ +--- +title: Subqueries +description: > + Subqueries (also known as inner queries or nested queries) are queries within + a query. Subqueries can be used in `SELECT`, `FROM`, `WHERE`, and `HAVING` clauses. +menu: + influxdb_cloud_serverless: + name: Subqueries + parent: SQL reference +weight: 210 +related: + - /influxdb/cloud-serverless/query-data/sql/ + - /influxdb/cloud-serverless/reference/sql/select/ + - /influxdb/cloud-serverless/reference/sql/where/ + - /influxdb/cloud-serverless/reference/sql/having/ +--- + +Subqueries (also known as inner queries or nested queries) are queries within +a query. +Subqueries can be used in `SELECT`, `FROM`, `WHERE`, and `HAVING` clauses. + +- [Subquery operators](#subquery-operators) + - [[ NOT ] EXISTS](#-not--exists) + - [[ NOT ] IN](#-not--in) +- [SELECT clause subqueries](#select-clause-subqueries) +- [FROM clause subqueries](#from-clause-subqueries) +- [WHERE clause subqueries](#where-clause-subqueries) +- [HAVING clause subqueries](#having-clause-subqueries) +- [Subquery categories](#subquery-categories) + - [Correlated subqueries](#correlated-subqueries) + - [Non-correlated subqueries](#non-correlated-subqueries) + - [Scalar subqueries](#scalar-subqueries) + - [Non-scalar subqueries](#non-scalar-subqueries) + +{{% note %}} +#### Sample data + +Query examples on this page use the following sample data sets: + +- [Get started home sensor sample data](/influxdb/cloud-serverless/reference/sample-data/#get-started-home-sensor-data) +- [Home sensor actions sample data](/influxdb/cloud-serverless/reference/sample-data/#home-sensor-actions-data) +- [NOAA Bay Area weather sample data](/influxdb/cloud-serverless/reference/sample-data/#noaa-bay-area-weather-data) + +{{% /note %}} + +## Subquery operators + +- [[ NOT ] EXISTS](#-not--exists) +- [[ NOT ] IN](#-not--in) + +### [ NOT ] EXISTS + +The `EXISTS` operator returns all rows where a +_[correlated subquery](#correlated-subquery)_ produces one or more matches for +that row. `NOT EXISTS` returns all rows where a _correlated subquery_ produces +zero matches for that row. Only _correlated subqueries_ are supported. + +#### Syntax {#-not-exists-syntax} + +```sql +[NOT] EXISTS (subquery) +``` + +### [ NOT ] IN + +The `IN` operator returns all rows where a given expression’s value can be found +in the results of a _[correlated subquery](#correlated-subqueries)_. +`NOT IN` returns all rows where a given expression’s value cannot be found in +the results of a subquery or list of values. + +#### Syntax {#-not-in-syntax} + +```sql +expression [NOT] IN (subquery|list-literal) +``` + +#### Examples {#-not-in-examples} + +{{< expand-wrapper >}} +{{% expand "View `IN` examples using a query" %}} +{{< code-tabs-wrapper >}} +{{% code-tabs %}} +[IN](#) +[NOT IN](#) +{{% /code-tabs %}} +{{% code-tab-content %}} +```sql +SELECT + time, + room, + temp +FROM + home +WHERE + room IN ( + SELECT + DISTINCT room + FROM + home_actions + ) +``` +{{% /code-tab-content %}} +{{% code-tab-content %}} +```sql +SELECT + time, + room, + temp +FROM + home +WHERE + room NOT IN ( + SELECT + DISTINCT room + FROM + home_actions + ) +``` +{{% /code-tab-content %}} +{{< /code-tabs-wrapper >}} +{{% /expand %}} + +{{% expand "View `IN` examples using a list literal" %}} +{{< code-tabs-wrapper >}} +{{% code-tabs %}} +[IN](#) +[NOT IN](#) +{{% /code-tabs %}} +{{% code-tab-content %}} +```sql +SELECT + time, + room, + temp +FROM home +WHERE room IN ('Bathroom', 'Bedroom', 'Kitchen') +``` +{{% /code-tab-content %}} +{{% code-tab-content %}} +```sql +SELECT + time, + room, + temp +FROM home +WHERE room NOT IN ('Bathroom', 'Bedroom', 'Kitchen') +``` +{{% /code-tab-content %}} +{{< /code-tabs-wrapper >}} +{{% /expand %}} + +{{< /expand-wrapper >}} + +## SELECT clause subqueries + +`SELECT` clause subqueries use values returned from inner query as part +of the outer query's `SELECT` list. +The `SELECT` clause only supports [scalar subqueries](#scalar-subqueries) that +return a single value per execution of the inner query. +The returned value can be unique per row. + +### Syntax {#select-subquery-syntax} + +```sql +SELECT [expression1[, expression2, ..., expressionN],] () +``` + +{{% note %}} +`SELECT` clause subqueries can be used as an alternative to `JOIN` operations. +{{% /note %}} + +### Examples {#select-subquery-examples} + +{{< expand-wrapper >}} +{{% expand "`SELECT` clause with correlated subquery" %}} + +```sql +SELECT + time, + room, + co, + ( + SELECT + MAX(description) + FROM + home_actions + WHERE + time = home.time + AND room = home.room + AND level != 'ok' + ) AS "Alert Description" +FROM + home +ORDER BY + room, + time +``` + +#### Inner query results + +Because the inner query is a [correlated subquery](#correlated-subqueries), +the result depends on the values of `room` and `time` columns in the outer query. +The results below represent the action description for each `room` and `time` +combination with a `level` value that does not equal `ok`. + +{{% influxdb/custom-timestamps %}} +| time | room | MAX(home_actions.description) | +| :------------------- | :---------- | :------------------------------------------ | +| 2022-01-01T18:00:00Z | Kitchen | Carbon monoxide level above normal: 18 ppm. | +| 2022-01-01T19:00:00Z | Kitchen | Carbon monoxide level above normal: 22 ppm. | +| 2022-01-01T20:00:00Z | Kitchen | Carbon monoxide level above normal: 26 ppm. | +| 2022-01-01T19:00:00Z | Living Room | Carbon monoxide level above normal: 14 ppm. | +| 2022-01-01T20:00:00Z | Living Room | Carbon monoxide level above normal: 17 ppm. | +{{% /influxdb/custom-timestamps %}} + +#### Outer query results + +{{% influxdb/custom-timestamps %}} +| time | room | co | Alert Description | +| :------------------- | :---------- | --: | :------------------------------------------ | +| 2022-01-01T08:00:00Z | Kitchen | 0 | | +| 2022-01-01T09:00:00Z | Kitchen | 0 | | +| 2022-01-01T10:00:00Z | Kitchen | 0 | | +| 2022-01-01T11:00:00Z | Kitchen | 0 | | +| 2022-01-01T12:00:00Z | Kitchen | 0 | | +| 2022-01-01T13:00:00Z | Kitchen | 1 | | +| 2022-01-01T14:00:00Z | Kitchen | 1 | | +| 2022-01-01T15:00:00Z | Kitchen | 3 | | +| 2022-01-01T16:00:00Z | Kitchen | 7 | | +| 2022-01-01T17:00:00Z | Kitchen | 9 | | +| 2022-01-01T18:00:00Z | Kitchen | 18 | Carbon monoxide level above normal: 18 ppm. | +| 2022-01-01T19:00:00Z | Kitchen | 22 | Carbon monoxide level above normal: 22 ppm. | +| 2022-01-01T20:00:00Z | Kitchen | 26 | Carbon monoxide level above normal: 26 ppm. | +| 2022-01-01T08:00:00Z | Living Room | 0 | | +| 2022-01-01T09:00:00Z | Living Room | 0 | | +| 2022-01-01T10:00:00Z | Living Room | 0 | | +| 2022-01-01T11:00:00Z | Living Room | 0 | | +| 2022-01-01T12:00:00Z | Living Room | 0 | | +| 2022-01-01T13:00:00Z | Living Room | 0 | | +| 2022-01-01T14:00:00Z | Living Room | 0 | | +| 2022-01-01T15:00:00Z | Living Room | 1 | | +| 2022-01-01T16:00:00Z | Living Room | 4 | | +| 2022-01-01T17:00:00Z | Living Room | 5 | | +| 2022-01-01T18:00:00Z | Living Room | 9 | | +| 2022-01-01T19:00:00Z | Living Room | 14 | Carbon monoxide level above normal: 14 ppm. | +| 2022-01-01T20:00:00Z | Living Room | 17 | Carbon monoxide level above normal: 17 ppm. | +{{% /influxdb/custom-timestamps %}} + +{{% /expand %}} +{{< /expand-wrapper >}} + +## FROM clause subqueries + +`FROM` clause subqueries return a set of results that is then queried and +operated on by the outer query. + +### Syntax {#from-subquery-syntax} + +```sql +SELECT expression1[, expression2, ..., expressionN] FROM () +``` + +### Examples {#from-subquery-examples} + +{{< expand-wrapper >}} +{{% expand "View `FROM` clause subquery example" %}} + +The following query returns the average of maximum values per room. +The inner query returns the maximum value for each field from each room. +The outer query uses the results of the inner query and returns the average +maximum value for each field. + +```sql +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 + ) +``` + +#### Inner query results + +| room | max_co | max_hum | max_temp | +| :---------- | -----: | ------: | -------: | +| Living Room | 17 | 36.4 | 22.8 | +| Kitchen | 26 | 36.9 | 23.3 | + +#### Outer query results + +| avg_max_co | avg_max_hum | avg_max_temp | +| ---------: | ----------: | -----------: | +| 21.5 | 36.7 | 23.1 | + +{{% /expand %}} +{{< /expand-wrapper >}} + +## WHERE clause subqueries + +[`WHERE` clause](/influxdb/cloud-serverless/reference/sql/where/) subqueries +compare an expression to the result of the subquery and return _true_ or _false_. +Rows that evaluate to _false_ are filtered from results. +The `WHERE` clause supports correlated and non-correlated subqueries +as well as scalar and non-scalar subqueries (depending on the the operator used +in the predicate expression). + +### Syntax {#where-subquery-syntax} + +```sql +SELECT + expression1[, expression2, ..., expressionN] +FROM + +WHERE + expression operator () +``` + +{{% note %}} +`WHERE` clause subqueries can be used as an alternative to `JOIN` operations. +{{% /note %}} + +### Examples {#where-subquery-examples} +{{< expand-wrapper >}} +{{% expand "`WHERE` clause with scalar subquery" %}} + +The following query returns all points with `temp` values above the average +of all `temp` values. The subquery returns the average `temp` value. + +```sql +SELECT + * +FROM + home +WHERE + temp > ( + SELECT + AVG(temp) + FROM + home + ) +``` + +#### Inner query result + +| AVG(home.temp) | +| :----------------- | +| 22.396153846153844 | + +#### Outer query result + +{{% influxdb/custom-timestamps %}} +| 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 | +{{% /influxdb/custom-timestamps %}} + +{{% /expand %}} +{{% expand "`WHERE` clause with non-scalar subquery" %}} + +Non-scalar subqueries must use the `[NOT] IN` operator and can only return a +single column. The values in the returned column are evaluated as a list. + +The following query returns all points in the `home` measurement associated with +the same timestamps as `warn` level alerts in the `home_actions` measurement. + +```sql +SELECT + * +FROM + home +WHERE + time IN ( + SELECT + DISTINCT time + FROM + home_actions + WHERE + level = 'warn' + ) +``` + +#### Inner query result + +{{% influxdb/custom-timestamps %}} +| time | +| :------------------- | +| 2022-01-01T18:00:00Z | +| 2022-01-01T19:00:00Z | +| 2022-01-01T20:00:00Z | +{{% /influxdb/custom-timestamps %}} + +#### Outer query result + +{{% influxdb/custom-timestamps %}} +| 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 | +{{% /influxdb/custom-timestamps %}} + +{{% /expand %}} +{{% expand "`WHERE` clause with correlated subquery" %}} + +The following query returns rows with temperature values greater than the median +temperature value for each room. The subquery in the `WHERE` clause uses the +`room` value from the outer query to return the median `temp` value for that +specific room. + +```sql +SELECT + time, + room, + temp +FROM + home outer_query +WHERE + temp > ( + SELECT + median(temp) AS temp + FROM + home + WHERE + room = outer_query.room + GROUP BY + room + ) +ORDER BY room, time +``` + +#### Inner query result + +The result of the inner query depends on the value of `room` in the outer query, +but the following table contains the median `temp` value for each room. + +| room | temp | +| :---------- | ---: | +| Living Room | 22.3 | +| Kitchen | 22.7 | + +#### Outer query result + +{{% influxdb/custom-timestamps %}} +| time | room | temp | +| :------------------- | :---------- | ---: | +| 2022-01-01T09:00:00Z | Kitchen | 23 | +| 2022-01-01T13:00:00Z | Kitchen | 22.8 | +| 2022-01-01T14:00:00Z | Kitchen | 22.8 | +| 2022-01-01T18:00:00Z | Kitchen | 23.3 | +| 2022-01-01T19:00:00Z | Kitchen | 23.1 | +| 2022-01-01T13:00:00Z | Living Room | 22.4 | +| 2022-01-01T16:00:00Z | Living Room | 22.4 | +| 2022-01-01T17:00:00Z | Living Room | 22.6 | +| 2022-01-01T18:00:00Z | Living Room | 22.8 | +| 2022-01-01T19:00:00Z | Living Room | 22.5 | +{{% /influxdb/custom-timestamps %}} + +{{% /expand %}} +{{< /expand-wrapper >}} + +## HAVING clause subqueries + +[`HAVING` clause](/influxdb/cloud-serverless/reference/sql/having/) subqueries +compare an expression that uses aggregate values returned by aggregate functions +in the `SELECT` clause to the result of the subquery and return _true_ or _false_. +Rows that evaluate to _false_ are filtered from results. +The `HAVING` clause supports correlated and non-correlated subqueries +as well as scalar and non-scalar subqueries (depending on the the operator used +in the predicate expression). + +### Syntax {#having-subquery-syntax} + +```sql +SELECT + aggregate_expression1[, aggregate_expression2, ..., aggregate_expressionN] +FROM + +WHERE + +GROUP BY + column_expression1[, column_expression2, ..., column_expressionN] +HAVING + expression operator () +``` + +### Examples {#having-subquery-examples} + +{{< expand-wrapper >}} +{{% expand "`HAVING` clause with scalar subquery" %}} + +The following query returns all two hour blocks of time with average `temp` values +greater then the median `temp` value. + +```sql +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 + ) +``` + +#### Inner query result + +| MEDIAN(home.temp) | +| :---------------- | +| 22.45 | + +#### Outer query result + +{{% influxdb/custom-timestamps %}} +| 2-hour block | 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 | +{{% /influxdb/custom-timestamps %}} + +{{% /expand %}} +{{% expand "`HAVING` clause with non-scalar subquery" %}} + +Non-scalar subqueries must use the `[NOT] IN` operator and can only return a +single column. The values in the returned column are evaluated as a list. + +The following query returns the maximum `co` and `temp` values within 2-hour +windows of time where the `time` value associated with time window is also +associated with a warning in the `home_actions` measurement. + +```sql +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' + ) +``` + +#### Inner query result + +{{% influxdb/custom-timestamps %}} +| time | +| :------------------- | +| 2022-01-01T18:00:00Z | +| 2022-01-01T19:00:00Z | +| 2022-01-01T20:00:00Z | +{{% /influxdb/custom-timestamps %}} + +#### Outer query result + +{{% influxdb/custom-timestamps %}} +| 2-hour block | 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 | +{{% /influxdb/custom-timestamps %}} + +{{% /expand %}} +{{% expand "`HAVING` clause with correlated subquery" %}} + +The following query returns 2-hour windows of time with average `temp` values +greater than the median `temp` value for each room. The subquery in the `HAVING` +clause uses the `room` value from the outer query to return the median `temp` value +for that specific room. + +```sql +SELECT + time, + room, + temp +FROM + home outer_query +WHERE + temp > ( + SELECT + median(temp) AS temp + FROM + home + WHERE + room = outer_query.room + GROUP BY + room + ) +ORDER BY room, time +``` + +#### Inner query result + +The result of the inner query depends on the value of `room` in the outer query, +but the following table contains the median `temp` value for each room. + +| room | temp | +| :---------- | ---: | +| Living Room | 22.3 | +| Kitchen | 22.7 | + +#### Outer query result + +{{% influxdb/custom-timestamps %}} +| 2-hour block | room | avg_temp | +| :------------------- | :---------- | -----------------: | +| 2022-01-01T14:00:00Z | Kitchen | 22.75 | +| 2022-01-01T18:00:00Z | Kitchen | 23.200000000000003 | +| 2022-01-01T16:00:00Z | Living Room | 22.5 | +| 2022-01-01T18:00:00Z | Living Room | 22.65 | +{{% /influxdb/custom-timestamps %}} + +{{% /expand %}} +{{< /expand-wrapper >}} + +## Subquery categories + +SQL subqueries can be categorized as one or more of the following base on the +behavior of the subquery: + +- [correlated](#correlated-subqueries) or [non-correlated](#non-correlated-subqueries) +- [scalar](#scalar-subqueries) or [non-scalar](#non-scalar-subqueries) + +### Correlated subqueries + +In a **correlated** subquery, the inner query depends on the outer query, using +values from the outer query for its results. +Correlated subqueries can return a maximum of one row, so +[aggregations](/influxdb/cloud-serverless/reference/sql/functions/aggregate/) may +be required in the inner query. + +In the query below, the inner query (`SELECT temp_avg FROM weather WHERE location = home.room`) +depends on data (`home.room`) from the outer query +(`SELECT time, room, temp FROM home`) and is therefore a _correlated_ subquery. + +```sql +SELECT + time, + room, + temp +FROM + home +WHERE + temp = ( + SELECT + temp_avg + FROM + weather + WHERE + location = home.room + ) +``` + +{{% note %}} +#### Correlated subquery performance + +Because correlated subqueries depend on the outer query and typically must +execute for each row returned by the outer query, correlated subqueries are +**less performant** than non-correlated subqueries. +{{% /note %}} + +### Non-correlated subqueries + +In a **non-correlated** subquery, the inner query _doesn't_ depend on the outer +query and executes independently. +The inner query executes first, and then passes the results to the outer query. + +In the query below, the inner query (`SELECT MIN(temp_avg) FROM weather`) can +run independently from the outer query (`SELECT time, temp FROM home`) and is +therefore a _non-correlated_ subquery. + +```sql +SELECT + time, + temp +FROM + home +WHERE + temp < ( + SELECT + MIN(temp_avg) + FROM + weather + ) +``` + +### Scalar subqueries + +A **scalar** subquery returns a single value (one column of one row). +If no rows are returned, the subquery returns NULL. + +The example subquery below returns the average value of a specified column. +This value is a single scalar value. + +```sql +SELECT * FROM home WHERE co > (SELECT avg(co) FROM home) +``` + +### Non-scalar subqueries + +A **non-scalar** subquery returns 0, 1, or multiple rows, each of which may +contain 1 or multiple columns. For each column, if there is no value to return, +the subquery returns NULL. If no rows qualify to be returned, the subquery +returns 0 rows. + +The example subquery below returns all distinct values in a column. +Multiple values are returned. + +```sql +SELECT * FROM home WHERE room IN (SELECT DISTINCT room FROM home_actions) +``` \ No newline at end of file diff --git a/content/influxdb/cloud-serverless/reference/sql/where.md b/content/influxdb/cloud-serverless/reference/sql/where.md index b35a0edec..02fcea227 100644 --- a/content/influxdb/cloud-serverless/reference/sql/where.md +++ b/content/influxdb/cloud-serverless/reference/sql/where.md @@ -8,6 +8,8 @@ menu: name: WHERE clause parent: SQL reference weight: 202 +related: + - /influxdb/cloud-serverless/reference/sql/subqueries/ --- Use the `WHERE` clause to filter results based on fields, tags, or timestamps.