neo4j - Neo4j Cypher 聚合函数在 WITH 子句中的变化
问题描述
我是 Neo4j 的新手,平均功能有问题。
我有一个银行账户(节点)和它们之间的支付(关系)的测试数据库。
我想计算每对账户之间的平均付款(即 A&B 之间、A&C 之间、B&C 之间等),然后找到任何高于平均值 50 美元的付款。
我的代码如下所示:
MATCH (a)-[r:Payment]-(b)
WITH a, b, AVG(ToFloat(r.Amount)) AS Average, ToFloat(r.Amount) as Amount
WHERE Amount-Average>50
RETURN a, b, Amount-Average AS Difference
如果我只在 WITH 子句中留下 a 和 Average,它似乎可以正确计算平均值,但如果我添加其他任何内容(r 或 r.Amount 子句),那么 Average 函数输出会发生变化,并且只返回相同的值值作为“金额”(因此它会将每个关系的“差异”计算为 0)。
难道是我匹配节点和关系的方式没有正确找到每对帐户之间的关系然后对它们进行平均,这会导致错误?
提前致谢!
解决方案
这是 Cypher 在执行聚合时隐式分组的结果。分组键(分组发生的上下文)是隐式的,由 WITH 或 RETURN 子句中存在的非聚合变量形成。
这就是为什么当您包含r
orr.amount
时,输出会发生变化,因为您将计算关于相同关系或相同数量的平均值(单个值的平均值就是该值)。
由于您要根据平均值评估和过滤节点之间的所有金额,因此您应该在取平均值时收集金额,然后过滤/转换内容以供返回。
此外,您需要包含一些过滤a
并b
确保不返回镜像结果(相同节点的结果相同,但a
交换的节点除外b
),因此我们将对节点 ID 使用限制确保仅在一个方向上订购:
MATCH (a)-[r:Payment]-(b)
WHERE id(a) < id(b) // ensure we don't get mirrored results
WITH a, b, AVG(ToFloat(r.Amount)) AS Average, collect(ToFloat(r.Amount)) as Amounts
WITH a, b, [amt in Amounts WHERE amt-Average > 50 | amt - Average] as Differences
RETURN a, b, Differences
如果您希望每一行都有单独的结果,那么您可以Differences
在返回之前 UNWIND 列表。
推荐阅读
- login - Yii2 登录验证密码失败
- ms-access - 使用权。如果记录为空,我该如何更改?
- swift - 使用 RxSwift 联网
- google-colaboratory - Google Colab - 如何使用代码重新启动运行时?
- vuetify.js - Vuetify 嵌套列表默认关闭
- python - Numpy 矩阵模索引提取
- node.js - 错误:在中间件中发送标头以进行 joi 验证后无法设置标头
- c# - json.net 反序列化返回 null
- jquery - $.ajax 调用未设置带有 crossDomain 和 xhrFields.withCredentials 的 cookie 设置为 true
- excel - excel vba数据从一张表传输到另一张错误只有标题复制没有任何数据