titlesidebar_labeldescription
WHERE keyword
WHERE
WHERE SQL keyword reference documentation.

WHERE clause filters data. Filter expressions are required to return boolean result.

Syntax

The general syntax is as follows. Specific filters have distinct syntaxes detailed thereafter.

Flow chart showing the syntax of the WHERE clause

Logical operators

QuestDB supports AND, OR, NOT as logical operators and can assemble conditions using brackets ().

Flow chart showing the detailed syntax of the WHERE clause

  1. SELECT * FROM table
  2. WHERE
  3. a = 1 AND (b = 2 OR c = 3 AND NOT d);

Symbol and string

QuestDB can filter strings and symbols based on equality, inequality, and regular expression patterns.

Exact match

Evaluates match of a string or symbol.

Flow chart showing the syntax of the WHERE clause with a string comparison

  1. SELECT * FROM users
  2. WHERE name = 'John';
nameage
John31
John45

Does NOT match

Evaluates mismatch of a string or symbol.

Flow chart showing the syntax of the WHERE clause with a string comparison

  1. SELECT * FROM users
  2. WHERE name != 'John';
nameage
Tim31
Tom45

Regular expression match

Evaluates match against a regular expression defined using java.util.regex patterns.

Flow chart showing the syntax of the WHERE clause with a regex comparison

  1. SELECT * FROM users WHERE name ~ 'Jo';
nameage
Joe31
Jonathan45

Regular expression does NOT match

Evaluates mismatch against a regular expression defined using java.util.regex patterns.

Flow chart showing the syntax of the WHERE clause with a regex comparison

  1. SELECT * FROM users WHERE name !~ 'Jo';
nameage
Tim31
Tom45

List search

Evaluates match or mismatch against a list of elements.

Flow chart showing the syntax of the WHERE clause with a list comparison

  1. SELECT * FROM users WHERE name in('Tim', 'Tom');
nameage
Tim31
Tom45
  1. SELECT * FROM users WHERE NOT name in('Tim', 'Tom');
nameage
Aaron31
Amelie45

Numeric

QuestDB can filter numeric values based on equality, inequality, comparison, and proximity

:::note

For timestamp filters, we recommend the timestamp search notation which is faster and less verbose.

:::

Equality, inequality and comparison

Flow chart showing the syntax of the WHERE clause with a numeric comparison

  1. SELECT * FROM users WHERE age >= 23;
  1. SELECT * FROM users WHERE age = 23;
  1. SELECT * FROM users WHERE age != 23;

Proximity

Evaluates whether the column value is within a range of the target value. This is useful to simulate equality on double and float values.

Flow chart showing the syntax of the WHERE clause with an EQ comparison

  1. SELECT * FROM users WHERE eq(age, 23, 0.00001);

:::tip

When performing multiple equality checks of double values against integer constants, it may be preferable to store double values as long integers with a scaling factor.

:::

Boolean

Flow chart showing the syntax of the WHERE clause with a boolean comparison

Using the columnName will return true values. To return false values, precede the column name with the NOT operator.

  1. SELECT * FROM users WHERE isActive;
userIdisActive
12532true
38572true
  1. SELECT * FROM users WHERE NOT isActive;
userIdisActive
876534false
43234false

Timestamp and date

QuestDB supports both its own timestamp search notation and standard search based on inequality. This section describes the use of the timestamp search notation which is efficient and fast but requires a designated timestamp.

If a table does not have a designated timestamp applied during table creation, one may be applied dynamically during a select operation.

Native timestamp format

QuestDB automatically recognizes strings formatted as ISO timestamp as a timestamp type. The following are valid examples of strings parsed as timestamp types:

Valid STRING FormatResulting Timestamp
2010-01-12T12:35:26.123456+01:302010-01-12T14:05:26.123456Z
2010-01-12T12:35:26.123456+012010-01-12T13:35:26.123456Z
2010-01-12T12:35:26.123456Z2010-01-12T12:35:26.123456Z
2010-01-12T12:35:26.123452010-01-12T12:35:26.123450Z
2010-01-12T12:35:26.12342010-01-12T12:35:26.123400Z
2010-01-12T12:35:26.1232010-01-12T12:35:26.123000Z
2010-01-12T12:35:26.122010-01-12T12:35:26.120000Z
2010-01-12T12:35:26.12010-01-12T12:35:26.100000Z
2010-01-12T12:35:262010-01-12T12:35:26.000000Z
2010-01-12T12:352010-01-12T12:35:00.000000Z
2010-01-12T122010-01-12T12:00:00.000000Z
2010-01-122010-01-12T00:00:00.000000Z
2010-012010-01-01T00:00:00.000000Z
20102010-01-01T00:00:00.000000Z
2010-01-12 12:35:26.123456-02:002010-01-12T10:35:26.123456Z
2010-01-12 12:35:26.123456Z2010-01-12T14:05:26.123456Z
2010-01-12 12:35:26.1232010-01-12T12:35:26.123000Z
2010-01-12 12:35:26.122010-01-12T12:35:26.120000Z
2010-01-12 12:35:26.12010-01-12T12:35:26.100000Z
2010-01-12 12:35:262010-01-12T12:35:26.000000Z
2010-01-12 12:352010-01-12T12:35:00.000000Z

Exact timestamp

Syntax

Flow chart showing the syntax of the WHERE clause with a timestamp comparison

  1. SELECT scores WHERE ts = '2010-01-12T00:02:26.000Z';
tsscore
2010-01-12T00:02:26.000Z2.4
2010-01-12T00:02:26.000Z3.1
  1. SELECT scores WHERE ts = '2010-01-12T00:02:26.000000Z';
tsscore
2010-01-12T00:02:26.000000Z2.4
2010-01-12T00:02:26.000000Z3.1

Time range

Return results within a defined range

Syntax

Flow chart showing the syntax of the WHERE clause with a partial timestamp comparison

  1. SELECT * FROM scores WHERE ts IN '2018';
tsscore
2018-01-01T00:0000.000000Z123.4
2018-12-31T23:59:59.999999Z115.8
  1. SELECT * FROM scores WHERE ts IN '2018-05-23T12:15';
tsscore
2018-05-23T12:15:00.000000Z123.4
2018-05-23T12:15:59.999999Z115.8

Time range with modifier

You can apply a modifier to further customize the range. The algorithm will calculate the resulting range by modifying the upper bound of the original range by the modifier parameter.

Syntax

Flow chart showing the syntax of the WHERE clause with a timestamp/modifier comparison

multiplier is a signed integer.

  • A positive value extends the interval.
  • A negative value reduces the interval.
  1. SELECT * FROM scores WHERE ts IN '2018;1M';

The range is 2018. The modifier extends the upper bound (originally 31 Dec 2018) by one month.

tsscore
2018-01-01T00:00:00.000000Z123.4
2019-01-31T23:59:59.999999Z115.8
  1. SELECT * FROM scores WHERE ts IN '2018-01;-3d';

The range is Jan 2018. The modifier reduces the upper bound (originally 31 Dec 2018) by 3 days.

tsscore
2018-01-01T00:00:00.000000Z123.4
2019-01-28T23:59:59.999999Z115.8

IN with multiple arguments

Syntax

IN with more than 1 argument is treated as standard SQL IN. It is a shorthand of multiple OR conditions, i.e. the following query:

  1. SELECT * FROM scores
  2. WHERE ts IN ('2018-01-01', '2018-01-01T12:00', '2018-01-02');

is equivalent to:

  1. SELECT * FROM scores
  2. WHERE ts = '2018-01-01' or ts = '2018-01-01T12:00' or ts = '2018-01-02');
tsvalue
2018-01-01T00:00:00.000000Z123.4
2018-01-01T12:00:00.000000Z589.1
2018-01-02T00:00:00.000000Z131.5

BETWEEN

Syntax

For non-standard ranges, users can explicitly specify the target range using the BETWEEN operator. As with standard SQL, both upper and lower bounds of BETWEEN are inclusive, and the order of lower and upper bounds is not important so that BETWEEN X AND Y is equivalent to BETWEEN Y AND X.

  1. SELECT * FROM scores
  2. WHERE ts BETWEEN '2018-01-01T00:00:23.000000Z' AND '2018-01-01T00:00:23.500000Z';
tsvalue
2018-01-01T00:00:23.000000Z123.4
2018-01-01T00:00:23.500000Z131.5

BETWEEN can accept non-constant bounds, for example, the following query will return all records older than one year before the current date:

  1. SELECT * FROM scores
  2. WHERE ts BETWEEN to_str(now(), 'yyyy-MM-dd')
  3. AND dateadd('y', -1, to_str(now(), 'yyyy-MM-dd'));