Comparison operations

Learn how to compare values in CQL.

Comparison operations allow you to determine whether one value is greater than, less than, or equal to another. These operations can be divided into two categories: equality and relational.

Equality checks whether two values are equal, while relational comparisons check the order of comparable values, such as numbers, strings, or dates.

This reference will guide you through the various comparison operations available in CQL and how to use them effectively.

Operations

Here is a quick summary of the available comparison operations in CQL:

OperationDescriptionOperator
EqualChecks if a value is equal to another.==
Not equalChecks if a value is not equal to another.!=
Greater thanChecks if a value is greater than another.>
Greater than or equalChecks if a value is greater than or equal to another.>=
Less thanChecks if a value is less than another.<
Less than or equalChecks if a value is less than or equal to another.<=

To make the language more intuitive and user-friendly, CQL also provides corresponding tests for each of these operations. For example, the > operator has a corresponding greater than test.

For more information on tests, refer to the tests reference.

Equal

The equal operation checks whether two values are equal. Unlike relational operations, it works on any value, not just values that have a concept of order.

To check whether two values are equal, place the == operator between them:

/*<operand>*/ == /*<operand>*/
Try in Playground

Here's a practical example involving strings:

"hello" == "hello" // true
Try in Playground

And another one involving numbers:

1 == 1.0 // true
Try in Playground

Although there is no natural language equivalent to the == operator, you can use the equal to test for a more natural reading:

/*<operand>*/ is equal to /*<operand>*/
Try in Playground

Note that operations and tests may differ in their behavior and precedence. Please refer to the documentation of each specific operation and test for more information.

Not equal

The not equal operation checks whether two values are different. Unlike relational operations, it works on any value, not just values that have a concept of order.

To check whether two values are different, place the != operator between them:

/*<operand>*/ != /*<operand>*/
Try in Playground

Here's a practical example involving strings:

"hello" != "Hello" // true
Try in Playground

And another one involving numbers:

1 != 1.1 // true
Try in Playground

Although there is no natural language equivalent to the != operator, you can use the not equal to test for a more natural reading:

/*<operand>*/ is not equal to /*<operand>*/
Try in Playground

Note that operations and tests may differ in their behavior and precedence. Please refer to the documentation of each specific operation and test for more information.

Greater than

The greater than operation checks whether one value is greater than another. You can use it to compare numbers, strings, dates, or any other value that has a concept of order.

To compare two values, place the > operator between them:

/*<operand>*/ > /*<operand>*/
Try in Playground

Here's a practical example involving numbers:

1 > 0 // true
Try in Playground

You can also compare strings alphabetically:

"b" > "a" // true
Try in Playground

And dates chronologically:

tomorrow > today // true
Try in Playground

Although there is no natural language equivalent to the > operator, you can use the greater than test for a more natural reading:

/*<operand>*/ is greater than /*<operand>*/
Try in Playground

Note that operations and tests may differ in their behavior and precedence. Please refer to the documentation of each specific operation and test for more information.

Greater or equal

The greater than or equal operation checks whether one value is greater than or equal to another. Like the greater than operation, it works with numbers, strings, dates, and other values that have a concept of order.

To compare two values, place the >= operator between them:

/*<operand>*/ >= /*<operand>*/
Try in Playground

Here's a practical example involving numbers:

1 >= 0 // true
Try in Playground

You can also compare strings alphabetically:

"b" >= "a" // true
Try in Playground

And dates chronologically:

tomorrow >= today // true
Try in Playground

Although there is no natural language equivalent to the >= operator, you can use the greater than or equal test for a more natural reading:

/*<operand>*/ is greater than or equal to /*<operand>*/
Try in Playground

Note that operations and tests may differ in their behavior and precedence. Please refer to the documentation of each specific operation and test for more information.

Less than

The less than operation checks whether one value is less than another. You can use it to compare numbers, strings, dates, or any other value that has a concept of order.

To compare two values, place the < operator between them:

/*<operand>*/ < /*<operand>*/
Try in Playground

Here's a practical example involving numbers:

0 < 1 // true
Try in Playground

You can also compare strings alphabetically:

"a" < "b" // true
Try in Playground

And dates chronologically:

today < tomorrow // true
Try in Playground

Although there is no natural language equivalent to the < operator, you can use the less than test for a more natural reading:

/*<operand>*/ is less than /*<operand>*/
Try in Playground

Note that operations and tests may differ in their behavior and precedence. Please refer to the documentation of each specific operation and test for more information.

Less or equal

The less than or equal operation checks whether one value is less than or equal to another. Like the less than operation, it works with numbers, strings, dates, and other values that have a concept of order.

To compare two values, place the <= operator between them:

/*<operand>*/ <= /*<operand>*/
Try in Playground

Here's a practical example involving numbers:

0 <= 1 // true
Try in Playground

You can also compare strings alphabetically:

"a" <= "b" // true
Try in Playground

And dates chronologically:

today <= tomorrow // true
Try in Playground

Although there is no natural language equivalent to the <= operator, you can use the less than or equal test for a more natural reading:

/*<operand>*/ is less than or equal to /*<operand>*/
Try in Playground

Note that operations and tests may differ in their behavior and precedence. Please refer to the documentation of each specific operation and test for more information.

Operation chaining

Typically, chaining multiple relational operations together is not allowed. That is because the result of the first operation is a boolean, and the second operation expects a number.

However, as in mathematics, CQL allows you to combine two relational operations in an interval-like notation. This is useful when checking whether a value is within a specific range.

For example, the following expression checks whether one value is between two other values, excluding the bounds:

/*<lower-bound>*/ < /*<operand>*/ < /*<upper-bound>*/
Try in Playground

Here is a practical example:

This reads as "x is greater than 1 and less than 3", which is equivalent to:

1 < x and x < 3
Try in Playground

To include the bounds in the range, use the <= and >= operators:

Note that you cannot chain more than two operations together:

1 < 2 < 3 < 4 // 🚨 Invalid
Try in Playground

Chained relational operations inherit the short-circuit optimization from the logical operation. This means that if the left side of the interval is false, the evaluation of the right side is skipped.

For example, consider the following expression:

Since the left side of the interval is false, the right side is not evaluated, making the entire interval false.

As a side note, you can alternatively use the between test to get the same result, but with a more natural language reading:

/*<operand>*/ is between /*<lower-bound>*/ and /*<upper-bound>*/
Try in Playground

General aspects

This section discusses some general aspects of comparison operations.

Equivalence

When comparing two values for equality, CQL follows the general rules of equivalence relations. One of these rules is the transitive property, which states that if a is equal to b and b is equal to c, then a is equal to c.

An example is the best way to illustrate the importance of this property for consistent comparisons:

1 == 1.0 and 1.0 == true and 1 == true
Try in Playground

If you look at the table of equivalence criteria below, you'll see that all three values are equivalent. As a result, the expression evaluates to true.

Here's a summary of the equivalence criteria for each type:

One operandOther operandEquality criteria
StringStringIf both strings are equal, character by character.
StringNullIf the string is empty.
NumberNumberIf both numbers are numerically equal.
NumberBooleanIf the number is equal to 1 for true or 0 for false.
BooleanBooleanIf both booleans are equal.
CollectionCollectionIf both collections contain the same keys and values in the same order.
Local dateLocal dateIf both local dates represent the same day.
Local timeLocal timeIf both local times represent the same time of day.
Local date-timeLocal date-timeIf both date-times represent the same date and time.
InstantInstantIf both instants represent the same point in time.
EnumEnumIf both enums represent the same value.
OtherOtherIf both values are the same type and logically equal.

Note that a local date-time is not equivalent to an instant, since they represent different concepts. The same applies to a local date and a local time.

To compare these values, you must convert them to the same type first. See the conversions section for more information.

Comparability

The relational operations only support a subset of the types available in CQL. More specifically, they only support types that have a concept of order.

Croct's mascot neutral
Don't compare apples and oranges

The operands in a comparison must be comparable. That is, they must be of the same or compatible types (e.g., integers and decimals).

Unlike other operations, relational operations do not attempt to convert the operands to a common type:

"1" > 0 // 🚨 Invalid
Try in Playground

To compare a number and a string, for example, you must either first convert the string to a number or the number to a string:

"1" as number > 0 // ✅ Valid
Try in Playground

The same applies to chronological comparisons:

session's start > "2024-01-01T12:00" as datetime
Try in Playground

This is necessary to ensure you get the expected result. For instance, comparing 10 and 2 as strings would give a different answer than comparing them as numbers. That is why you must convert the operands to a common type first.

The table below lists common types used in comparisons and how they are ordered:

TypeMethodDescription
StringAlphabeticalStrings are ordered alphabetically, character by character, using the lexicographical order.
NumberNumericalNumbers are arranged in standard numerical order, with smaller numbers appearing first.
Date-timeChronologicalDate and time values are ordered chronologically, from the earliest to the latest.