Source: https://dev-docs.yueshu.com.cn/v5.3.2/database-gql-reference/fe/expressions/subquery/ Documentation version: v5.3.2 # 子查询表达式 子查询表达式返回从某个查询中提取出的单个值或布尔值。 ## 语法 语法图源码 subquery_value_expression ```` subquery_value_expression ::= 'VALUE' '{' procedure_body '}' | 'EXISTS' '{' procedure_body '}' ```` ## 参数 ### `procedure_body` 过程的处理逻辑,可以由[原始值变量定义](https://dev-docs.yueshu.com.cn/v5.3.2/database-gql-reference/variable-definition/value-variable/)和以下类型的语句组成: - [数据查询语句](https://dev-docs.yueshu.com.cn/v5.3.2/database-gql-reference/dql/) - [控制流语句](https://dev-docs.yueshu.com.cn/v5.3.2/database-gql-reference/control-flow/) - [变量操作语句](https://dev-docs.yueshu.com.cn/v5.3.2/database-gql-reference/set/) - [日志语句](https://dev-docs.yueshu.com.cn/v5.3.2/database-gql-reference/log/) ### `VALUE | EXISTS` 子查询表达式的返回值类型。 - `VALUE`:返回单个值。为此,`procedure_body`中的 [RETURN 语句](https://dev-docs.yueshu.com.cn/v5.3.2/database-gql-reference/dql/return/)必须包含聚合返回项,或被`LIMIT 1`子句跟随。 - 如果`procedure_body`的结果为空表,则子查询表达式的结果为`NULL`。 - 如果`procedure_body`的结果是包含单个记录且单个字段的表,则子查询表达式的结果是该字段的值。 - `EXISTS`:返回一个布尔值,表示某个模式是否在图中出现至少一次。 - 如果`procedure_body`的执行结果是非空表,则子查询表达式的结果为`true`。 - 如果`procedure_body`的结果为空表,则子查询表达式的结果为`false`。 ### 工作图 子查询中可以使用[`USE`](https://dev-docs.yueshu.com.cn/v5.3.2/database-gql-reference/dql/clauses/use-graph/)声明工作图: - 如果子查询中没有`USE`,子查询继承外层查询的工作图。 - 如果子查询中使用`USE`指定另一张图,子查询可以访问该图,并将返回的标量值或布尔值提供给外层查询。 - 跨图关联数据时,建议为不同图中的图元素使用不同变量,并通过业务 ID 等属性值进行比较。 ## 示例 以下示例基于[示例数据集](https://dev-docs.yueshu.com.cn/v5.3.2/database-gql-reference/overview/example-dataset/)。 ### 使用 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. ````