COUNT 子查询
COUNT
子查询可用于计算子查询返回的行数。
示例图
以下示例使用此图:
要重新创建此图,请对空的 Neo4j 数据库运行以下查询:
CREATE
(andy:Swedish:Person {name: 'Andy', age: 36}),
(timothy:Person {name: 'Timothy', nickname: 'Tim', age: 25}),
(peter:Person {name: 'Peter', nickname: 'Pete', age: 35}),
(andy)-[:HAS_DOG {since: 2016}]->(:Dog {name:'Andy'}),
(timothy)-[:HAS_CAT {since: 2019}]->(:Cat {name:'Mittens'}),
(fido:Dog {name:'Fido'})<-[:HAS_DOG {since: 2010}]-(peter)-[:HAS_DOG {since: 2018}]->(:Dog {name:'Ozzy'}),
(fido)-[:HAS_TOY]->(:Toy{name:'Banana'})
简单的 COUNT
子查询
外部作用域引入的变量可以在 COUNT
子查询中使用,无需导入。在这方面,COUNT
子查询与 需要导入的 CALL
子查询 不同。以下查询示例说明了这一点,并输出拥有多只狗的主人:
MATCH (person:Person)
WHERE COUNT { (person)-[:HAS_DOG]->(:Dog) } > 1
RETURN person.name AS name
姓名 |
---|
|
行数:1 |
带有 WHERE
子句的 COUNT
子查询
WHERE
子句可以在 COUNT
模式内部使用。由 MATCH
子句和外部作用域引入的变量可以在此作用域中使用。
MATCH (person:Person)
WHERE COUNT {
(person)-[:HAS_DOG]->(dog:Dog)
WHERE person.name = dog.name
} = 1
RETURN person.name AS name
姓名 |
---|
|
行数:1 |
带有 UNION
的 COUNT
子查询
COUNT
可以与 UNION
子句一起使用。如果 UNION
子句是去重 (`DISTINCT`) 的,则需要 RETURN
子句。UNION ALL
子句不需要 RETURN
子句。然而,值得注意的是,如果其中一个分支有 RETURN
子句,那么所有分支都需要有。下面的示例显示了使用 UNION
子句计算每个人拥有的宠物数量:
MATCH (person:Person)
RETURN
person.name AS name,
COUNT {
MATCH (person)-[:HAS_DOG]->(dog:Dog)
RETURN dog.name AS petName
UNION
MATCH (person)-[:HAS_CAT]->(cat:Cat)
RETURN cat.name AS petName
} AS numPets
姓名 | 宠物数量 |
---|---|
|
|
|
|
|
|
行数:3 |
带有 WITH
的 COUNT
子查询
外部作用域的变量在整个子查询中可见,即使使用 WITH
子句也是如此。为避免混淆,不允许这些变量被遮蔽。当内部作用域中引入的新变量与外部作用域变量同名时,就会发生变量遮蔽。在下面的示例中,外部变量 name
被遮蔽,因此会抛出错误。
WITH 'Peter' as name
MATCH (person:Person {name: name})
WHERE COUNT {
WITH "Ozzy" AS name
MATCH (person)-[:HAS_DOG]->(d:Dog)
WHERE d.name = name
} = 1
RETURN person.name AS name
The variable `name` is shadowing a variable with the same name from the outer scope and needs to be renamed (line 4, column 20 (offset: 90))
可以向子查询引入新变量,只要它们使用不同的标识符。在下面的示例中,WITH
子句引入了一个新变量。请注意,主查询中引用的外部作用域变量 person
在 WITH
子句之后仍然可用。
MATCH (person:Person)
WHERE COUNT {
WITH "Ozzy" AS dogName
MATCH (person)-[:HAS_DOG]->(d:Dog)
WHERE d.name = dogName
} = 1
RETURN person.name AS name
姓名 |
---|
|
行数:1 |
在其他子句中使用 COUNT
子查询
COUNT
可以在查询中的任何位置使用,但管理命令除外,在管理命令中它会受到限制。请参阅下面的几个示例:
在 RETURN
中使用 COUNT
MATCH (person:Person)
RETURN person.name, COUNT { (person)-[:HAS_DOG]->(:Dog) } as howManyDogs
person.name | howManyDogs |
---|---|
|
|
|
|
|
|
行数:3 |
在 SET
中使用 COUNT
MATCH (person:Person) WHERE person.name ="Andy"
SET person.howManyDogs = COUNT { (person)-[:HAS_DOG]->(:Dog) }
RETURN person.howManyDogs as howManyDogs
howManyDogs |
---|
|
行数:1 |
在 CASE
中使用 COUNT
MATCH (person:Person)
RETURN
CASE
WHEN COUNT { (person)-[:HAS_DOG]->(:Dog) } > 1 THEN "Doglover " + person.name
ELSE person.name
END AS result
结果 |
---|
|
|
|
行数:3 |
将 COUNT
用作分组键
以下查询按每个人拥有的狗的数量对所有人进行分组,然后计算每个组的平均年龄。
MATCH (person:Person)
RETURN COUNT { (person)-[:HAS_DOG]->(:Dog) } AS numDogs,
avg(person.age) AS averageAge
ORDER BY numDogs
狗的数量 | 平均年龄 |
---|---|
|
|
|
|
|
|
行数:3 |
带有 RETURN
的 COUNT
子查询
COUNT
子查询在子查询末尾不需要 RETURN
子句。如果存在,则不需要为其设置别名。这是与 CALL
子查询 的区别。在 COUNT
子查询中返回的任何变量在子查询之后都将不可用。
MATCH (person:Person)
WHERE COUNT {
MATCH (person)-[:HAS_DOG]->(:Dog)
RETURN person.name
} = 1
RETURN person.name AS name
姓名 |
---|
|
行数:1 |