Skip to content
Developer Edition runs on one host and does not require a product license file. Need multi-host deployment or performance testing at scale? Explore Enterprise Edition

Subquery value expression

A subquery value expression returns a single value or a boolean value derived from a query.

Syntax

subquery_value_expression
VALUE { procedure_body } EXISTS { procedure_body }

subquery_value_expression ::=
    'VALUE' '{' procedure_body '}'
  | 'EXISTS' '{' procedure_body '}'

Parameters

procedure_body

The processing logic of a procedure. It can consist of primitive value variable definitions and statements of the following types:

VALUE | EXISTS

The type of the return value of the subquery value expression.

  • VALUE: Returns a single value. To ensure that, the RETURN statement in procedure_body should either contain an aggregate return item or be followed by the LIMIT 1 clause.
    • If the result of procedure_body is an empty table, the result of the subquery value expression is NULL.
    • If the result of procedure_body is a table comprising a single record with a single field, the result is the value of the field.
  • EXISTS: Returns a boolean value that indicates whether a specified pattern exists at least once in the graph.
    • If the execution result of procedure_body is a non-empty table, the result of the subquery value expression is true.
    • If the execution result of procedure_body is an empty table, the result of the subquery value expression is false.

Working graph

A subquery can use USE to declare a working graph:

  • If the subquery does not contain USE, it inherits the working graph of the outer query.
  • If the subquery uses USE to specify another graph, it can access that graph and provide a scalar or Boolean value to the outer query.
  • When associating data across graphs, use different variables for graph elements from different graphs and compare properties such as business IDs.

Examples

The following example is based on the example dataset.

A subquery returning a single value with LIMIT 1

RETURN VALUE {FOR i IN LIST [1,2,3,4] RETURN i ORDER BY i LIMIT 1} AS subquery_result

The preceding statement uses the subquery VALUE {FOR i IN LIST [1,2,3,4] RETURN i ORDER BY i LIMIT 1} to find the smallest value in the list [1,2,3,4] and returns the value.

Return:

+-----------------+
| subquery_result |
+-----------------+
| 1               |
+-----------------+

A subquery returning NULL

RETURN VALUE {FOR i IN LIST [] RETURN i ORDER BY i LIMIT 1} AS subquery_result

The preceding statement uses the subquery VALUE {FOR i IN LIST [] RETURN i ORDER BY i LIMIT 1} to find the empty value in the empty list [] and returns the NULL value.

Return:

+-----------------+
| subquery_result |
+-----------------+
| null            |
+-----------------+

A subquery returning a boolean value

'''
USE movie MATCH (a@Actor)
WHERE EXISTS {USE movie MATCH (v@Actor) RETURN v}
RETURN a.name
Limit 5
'''

The preceding statement uses the EXISTS subquery block to find out if any actor exists in the graph. If yes, the statement returns the names of five actors in the graph.

Return:

+------------------------+
| a.name                 |
+------------------------+
| Wilfried Hochholdinger |
| Martin LaSalle         |
| Lenny McLean           |
| Tadanobu Asano         |
| David Prowse           |
+------------------------+

Switch working graphs in a subquery

The following query matches movies in movie and uses an EXISTS {} subquery to check whether a movie with the same business ID exists in movie_2:

'''
USE movie
MATCH (m:Movie)
WHERE EXISTS {
  USE movie_2
  MATCH (m2:Movie)
  WHERE m2.id = m.id
  RETURN m2
}
RETURN m.id, m.name
'''

The outer query and subquery use m and m2 respectively for graph elements from the two graphs, and associate the data through the business property id.

A subquery containing control flow statements

'''
USE movie MATCH (a@Actor)
LET v = VALUE {
    VALUE d = DATE "1950-01-01"
    IF a.birthDate > d THEN {
        RETURN "born_after_1950" AS result        
    } ELSE {
        RETURN "born_before_1950" AS result
    }
 }
RETURN a.name, v
LIMIT 5
'''

The preceding statement uses the VALUE subquery block containing the IF control flow statement to check whether the birth date of each actor is after January 1, 1950. It then returns the names of five actors along with the check results.

Return:

+------------------+------------------+
| a.name           | v                |
+------------------+------------------+
| Jacques Weber    | born_before_1950 |
| Chia Hui Liu     | born_after_1950  |
| Ulrich Noethen   | born_after_1950  |
| Richard Pachorek | born_before_1950 |
| Christian Bale   | born_after_1950  |
+------------------+------------------+

A subquery containing variable manipulation statements

'''
USE movie MATCH (v@Actor) WHERE v.id IN [1,2,3,4,5]
LET d = VALUE {
  VALUE born_before_1950 = true
  IF v.birthDate < DATE "1950-01-01" THEN 
    {    
      SET born_before_1950 = true
      LOG_INFO(v.name, " was born before 1950.")
     } 
  ELSE 
    {  
      SET born_before_1950  = false     
      LOG_INFO(v.name, " was born in or after 1950.")
    }
  RETURN born_before_1950
  }
RETURN v.name, d AS born_before_1950  
'''

The preceding statement uses the VALUE subquery block containing variable manipulation statements to check whether the birth date of each actor with IDs 1 to 5 is before January 1, 1950. It then returns the names of the actors along with the check results.

Return:

+---------------+------------------+
| v.name        | born_before_1950 |
+---------------+------------------+
| Harrison Ford | true             |
| Mark Hamill   | false            |
| Peter Cushing | true             |
| Carrie Fisher | false            |
+---------------+------------------+
Log:
2026-01-20T10:07:47.149974 INFO  - Mark Hamill was born in or after 1950.
2026-01-20T10:07:47.149975 INFO  - Harrison Ford was born before 1950.
2026-01-20T10:07:47.150058 INFO  - Peter Cushing was born before 1950.
2026-01-20T10:07:47.150317 INFO  - Carrie Fisher was born in or after 1950.