图数据库 Cypher 查询语言的子查询 CALL (subquery)
目录
子查询允许将查询组合起来,这在使用UNION
或聚合时特别有用。
子查询与封闭查询交互的方式有一些限制:
- 子查询只能引用外部查询中显式导入的变量。
- 子查询不能返回与外围查询中变量名称相同的变量。
- 从子查询返回的所有变量随后都可在外部查询中使用。
WITH
导入变量进子句必须:
- 只包含对外部变量的简单引用,例如
WITH x, y, z
。导入WITH
子句时不支持别名或表达式,例如~~WITH a AS b~~
或~~WITH a+1 AS b~~
。 - 是子查询的第一个子句(如果直接跟在
USE
子句后面,则是第二个子句)。
官方例子:
MATCH (p:Person)
CALL {
WITH p
MATCH (p)-[:FRIEND_OF]-(c:Person)
RETURN c.name AS friend
}
RETURN p.name, friend
# 不返回任何行的单元子查询,会产生副作用
MATCH (p:Person)
CALL {
WITH p
UNWIND range (1, 5) AS i
CREATE (:Person {name: p.name})
}
RETURN count(*)
我的举例:
# 查询医生兼职的组织数量的最大值
MATCH (n:Doctor)
CALL {
WITH n
MATCH (n) -[:WORK_IN]-> (e:Organization)
RETURN count(n) as cnt
}
RETURN max(cnt)
# 查询医生工作医院、科室、组织的职位数量的最大值
MATCH (n:Doctor)
CALL {
WITH n
CALL {
WITH n
MATCH (n) -[r1:WORK_IN]-> (e:Organization)
WHERE r1.position is not NULL
RETURN count(r1) as cnt1
}
CALL {
WITH n
MATCH (n) -[r1:WORK_IN]-> (e:Hospital)
WHERE r1.position is not NULL
RETURN count(r1) as cnt2
}
CALL {
WITH n
MATCH (n) -[r1:WORK_IN]-> (e:Department)
WHERE r1.position is not NULL
RETURN count(r1) as cnt3
}
RETURN cnt1 + cnt2 + cnt3 AS cnt
}
RETURN max(cnt) as max_cnt
# 查找众数:计数+排序
MATCH (d:Doctor)
CALL {
WITH d
RETURN d.clinicProfessional AS cp
}
RETURN d.clinicProfessional, count(cp)
典型应用场景:需要结果的不同部分进行不同匹配,然后在整个结果上做一个汇总,比如查询每个人的朋友数量。
WITH 给我的感觉就像是 SQL 中的 WITH 给子查询起别名一样
子查询的作用:子查询可用于对每一行进行汇总
参考文献
Neo4j 版本4 新特性介绍 - Cypher [1] CALL 子查询_neo4j call_俞博士的博客-CSDN博客