子查询表达式¶
子查询表达式返回从某个查询中提取出的单个值或布尔值。
语法¶
- subquery_value_expression
subquery_value_expression ::=
'VALUE' '{' procedure_body '}'
| 'EXISTS' '{' procedure_body '}'
参数¶
procedure_body¶
过程的处理逻辑,可以由原始值变量定义和以下类型的语句组成:
VALUE | EXISTS¶
子查询表达式的返回值类型。
VALUE:返回单个值。为此,procedure_body中的 RETURN 语句必须包含聚合返回项,或被LIMIT 1子句跟随。- 如果
procedure_body的结果为空表,则子查询表达式的结果为NULL。 - 如果
procedure_body的结果是包含单个记录且单个字段的表,则子查询表达式的结果是该字段的值。
- 如果
EXISTS:返回一个布尔值,表示某个模式是否在图中出现至少一次。- 如果
procedure_body的执行结果是非空表,则子查询表达式的结果为true。 - 如果
procedure_body的结果为空表,则子查询表达式的结果为false。
- 如果
工作图¶
子查询中可以使用USE声明工作图:
- 如果子查询中没有
USE,子查询继承外层查询的工作图。 - 如果子查询中使用
USE指定另一张图,子查询可以访问该图,并将返回的标量值或布尔值提供给外层查询。 - 跨图关联数据时,建议为不同图中的图元素使用不同变量,并通过业务 ID 等属性值进行比较。
示例¶
以下示例基于示例数据集。
使用 LIMIT 1 返回单个值的子查询¶
RETURN VALUE {FOR i IN LIST [1,2,3,4] RETURN i ORDER BY i LIMIT 1} AS subquery_result
上述语句使用子查询VALUE {FOR i IN LIST [1,2,3,4] RETURN i ORDER BY i LIMIT 1}来查找列表[1,2,3,4]中的最小值,并返回该值。
返回:
+-----------------+
| subquery_result |
+-----------------+
| 1 |
+-----------------+
返回 NULL 的子查询¶
RETURN VALUE {FOR i IN LIST [] RETURN i ORDER BY i LIMIT 1} AS subquery_result
上述语句使用子查询VALUE {FOR i IN LIST [] RETURN i ORDER BY i LIMIT 1}来查找列表[]中的空值,并返回NULL值。
返回:
+-----------------+
| subquery_result |
+-----------------+
| null |
+-----------------+
返回布尔值的子查询¶
'''
USE movie MATCH (a@Actor)
WHERE EXISTS {USE movie MATCH (v@Actor) RETURN v}
RETURN a.name
Limit 5
'''
上述语句使用子查询EXISTS {}来查找图中是否存在任何演员。如果存在,则返回图中的五个演员的名称。
返回:
+------------------------+
| a.name |
+------------------------+
| Wilfried Hochholdinger |
| Martin LaSalle |
| Lenny McLean |
| Tadanobu Asano |
| David Prowse |
+------------------------+
在子查询中切换工作图¶
下面的查询在movie中匹配电影,并通过EXISTS {}子查询检查同一业务 ID 的电影是否存在于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
'''
外层查询和子查询分别使用变量m和m2表示两张图中的图元素,并通过业务属性id关联数据。
包含控制流语句的子查询¶
'''
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
'''
上述语句使用包含IF控制流语句的子查询VALUE {}来检查每个演员的出生日期是否在 1950 年 1 月 1 日之后。然后返回五个演员的姓名及检查结果。
返回:
+------------------+------------------+
| 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 |
+------------------+------------------+
包含变量操作语句的子查询¶
'''
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
'''
上述语句使用包含变量操作语句的子查询VALUE {}来检查 ID 在 1 到 5 之间的演员的出生日期是否在 1950 年 1 月 1 日之前。然后返回这些演员的姓名及检查结果。
返回:
+---------------+------------------+
| 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.