我是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)。
难道是我匹配节点和关系的方式没有正确找到每对帐户之间的关系,然后对它们进行平均,这会导致错误吗?
谢谢!
答案 0 :(得分:0)
这是执行聚合时Cypher隐式分组的结果。分组键(分组发生的上下文)是隐式的,由WITH或RETURN子句中存在的非聚合变量形成。
这就是为什么当您包含r
或r.amount
时,输出会发生变化,因为您将针对相同的关系或相同的数量(单个平均值的平均值)计算平均值价值就是那个价值。)
由于您要基于平均值评估和过滤节点之间的所有金额,因此在获取平均值时应收集金额,然后对内容进行过滤/转换以供返回。
此外,您还希望对a
和b
进行一些过滤,以确保您不返回镜像结果(除了{{1 }}和a
交换),因此我们将对节点ID进行限制,以确保仅在单个方向上订购:
b
如果您希望每一行都有单独的结果,则可以在退回之前取消缠绕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
列表。