content/shared/influxdb-v2/reference/syntax/flux/flux-vs-influxql.md
Flux is an alternative to InfluxQL and other SQL-like query languages for querying and analyzing data. Flux uses functional language patterns that overcome many InfluxQL limitations. Check out the following distinctions between Flux and InfluxQL:
InfluxQL has never supported joins. Although you can use a join in a TICKscript,
TICKscript's join capabilities are limited.
Flux's join() function lets you
join data from any bucket, any measurement, and on any columns as long as
each data set includes the columns to join on.
dataStream1 = from(bucket: "example-bucket1")
|> range(start: -1h)
|> filter(fn: (r) => r._measurement == "network" and r._field == "bytes-transferred")
dataStream2 = from(bucket: "example-bucket2")
|> range(start: -1h)
|> filter(fn: (r) => r._measurement == "httpd" and r._field == "requests-per-sec")
join(tables: {d1: dataStream1, d2: dataStream2}, on: ["_time", "_stop", "_start", "host"])
For an in-depth walkthrough of using the join() function, see how to join data with Flux.
Being able to perform joins across measurements lets you calculate
data from separate measurements.
The example below takes data from two measurements, mem and processes,
joins them, and then calculates the average amount of memory used per running process:
// Memory used (in bytes)
memUsed = from(bucket: "example-bucket")
|> range(start: -1h)
|> filter(fn: (r) => r._measurement == "mem" and r._field == "used")
// Total processes running
procTotal = from(bucket: "example-bucket")
|> range(start: -1h)
|> filter(fn: (r) => r._measurement == "processes" and r._field == "total")
// Join memory used with total processes to calculate
// the average memory (in MB) used for running processes.
join(tables: {mem: memUsed, proc: procTotal}, on: ["_time", "_stop", "_start", "host"])
|> map(fn: (r) => ({_time: r._time, _value: r._value_mem / r._value_proc / 1000000}))
InfluxQL's sorting capabilities only let you control the
sort order of time using the ORDER BY time clause.
The Flux sort() function
sorts records based on a list of columns.
Depending on the column type, Flux sorts records lexicographically, numerically, or chronologically.
from(bucket: "example-bucket")
|> range(start: -12h)
|> filter(fn: (r) => r._measurement == "system" and r._field == "uptime")
|> sort(columns: ["region", "host", "_value"])
InfluxQL lets you group by tags or time intervals only.
Flux lets you group data by any column, including _value.
Use the Flux group() function
to define which columns to group data by.
from(bucket:"example-bucket")
|> range(start: -12h)
|> filter(fn: (r) => r._measurement == "system" and r._field == "uptime" )
|> group(columns:["host", "_value"])
InfluxQL does not support windowing data by calendar months and years due to their varied lengths.
Flux supports calendar month and year duration units (1mo, 1y) and lets you
window and aggregate data by calendar month and year.
from(bucket:"example-bucket")
|> range(start:-1y)
|> filter(fn: (r) => r._measurement == "mem" and r._field == "used_percent" )
|> aggregateWindow(every: 1mo, fn: mean)
InfluxQL can only query data stored in InfluxDB. Flux can query data from other data sources such as CSV, PostgreSQL, MySQL, Google BigTable, and more. Join that data with data in InfluxDB to enrich query results.
<!-- -->import "csv"
import "sql"
csvData = csv.from(csv: rawCSV)
sqlData = sql.from(
driverName: "postgres",
dataSourceName: "postgresql://user:password@localhost",
query: "SELECT * FROM example_table",
)
data = from(bucket: "example-bucket")
|> range(start: -24h)
|> filter(fn: (r) => r._measurement == "sensor")
auxData = join(tables: {csv: csvData, sql: sqlData}, on: ["sensor_id"])
enrichedData = join(tables: {data: data, aux: auxData}, on: ["sensor_id"])
enrichedData
|> yield(name: "enriched_data")
For an in-depth walkthrough of querying SQL data, see Query SQL data sources.
InfluxQL doesn't support DatePart-like queries that only return results during specified hours of the day.
The Flux hourSelection function
returns only data with time values in a specified hour range.
from(bucket: "example-bucket")
|> range(start: -1h)
|> filter(fn: (r) => r._measurement == "cpu" and r.cpu == "cpu-total")
|> hourSelection(start: 9, stop: 17)
Pivoting data tables isn't supported in InfluxQL.
Use the Flux pivot() function
to pivot data tables by rowKey, columnKey, and valueColumn parameters.
from(bucket: "example-bucket")
|> range(start: -1h)
|> filter(fn: (r) => r._measurement == "cpu" and r.cpu == "cpu-total")
|> pivot(rowKey: ["_time"], columnKey: ["_field"], valueColumn: "_value")
Generating histograms isn't supported in InfluxQL.
Use the Flux histogram() function to
generate a cumulative histogram.
from(bucket: "example-bucket")
|> range(start: -1h)
|> filter(fn: (r) => r._measurement == "mem" and r._field == "used_percent")
|> histogram(buckets: [10, 20, 30, 40, 50, 60, 70, 80, 90, 100])
For more examples, see how to create histograms with Flux.
Flux provides functions for simple covariance calculations.
Use the covariance() function
to calculate the covariance between two columns and the cov() function
to calculate the covariance between two data streams.
from(bucket: "example-bucket")
|> range(start:-5m)
|> covariance(columns: ["x", "y"])
table1 = from(bucket: "example-bucket")
|> range(start: -15m)
|> filter(fn: (r) => r._measurement == "measurement_1")
table2 = from(bucket: "example-bucket")
|> range(start: -15m)
|> filter(fn: (r) => r._measurement == "measurement_2")
cov(x: table1, y: table2, on: ["_time", "_field"])
InfluxQL supports type casting for numeric data types (floats to integers and vice versa) only. Use Flux type conversion functions to perform many more type conversions, including casting boolean values to integers.
from(bucket: "example-bucket")
|> range(start: -1h)
|> filter(fn: (r) => r._measurement == "m" and r._field == "bool_field")
|> toInt()
InfluxQL doesn't support string manipulation when querying data.
Use Flux Strings package functions to operate on string data.
Combine functions in this package with the map() function to perform operations like sanitizing and normalizing strings.
import "strings"
from(bucket: "example-bucket")
|> range(start: -1h)
|> filter(fn: (r) => r._measurement == "weather" and r._field == "temp")
|> map(
fn: (r) => ({
r with
location: strings.toTitle(v: r.location),
sensor: strings.replaceAll(v: r.sensor, t: " ", u: "-"),
status: strings.substring(v: r.status, start: 0, end: 8)
})
)
InfluxQL doesn't support working with geo-temporal data. The Flux Geo package is a collection of functions that let you shape, filter, and group geo-temporal data.
import "experimental/geo"
from(bucket: "geo/autogen")
|> range(start: -1w)
|> filter(fn: (r) => r._measurement == "taxi")
|> geo.shapeData(latField: "latitude", lonField: "longitude", level: 20)
|> geo.filterRows(region: {lat: 40.69335938, lon: -73.30078125, radius: 20.0}, strict: true)
|> geo.asTracks(groupBy: ["fare-id"])
We're continuing to add functions to complete parity between Flux and InfluxQL. The table below shows InfluxQL statements, clauses, and functions along with their equivalent Flux functions.
For a complete list of Flux functions, view all Flux functions.