首先,我研究了Can Neo4j Cypher query do similar thing as "Having" in SQL?和https://neo4j.com/developer/kb/how-do-i-achieve-the-equivalent-of-a-sql-having-clause-with-cypher/。他们俩都有相似的建议,但是对于我来说似乎不起作用(也许是因为我有UNWIND子句?)。
这是我的查询:
MATCH (a:MyNode)-[:SOME_RELATIONSHIP]->()<-[:SOME_RELATIONSHIP]-(b:MyNode {prop: 'value'})
WHERE a.prop<>'value'
WITH collect(b) AS excluded
MATCH (m:MyNode {prop: 'value'})
WITH excluded, COLLECT(m) AS superset
UNWIND [n IN superset WHERE NOT n IN excluded] AS t
RETURN t.propTwo, COUNT(DISTINCT(t.propThree))
这对我来说很好。问题是它返回数为1的数千行,而返回数为大于1的几行。我只希望计数大于1的行。按照上述链接的建议,我想到了< / p>
MATCH (a:MyNode)-[:SOME_RELATIONSHIP]->()<-[:SOME_RELATIONSHIP]-(b:MyNode {prop: 'value'})
WHERE a.prop<>'value'
WITH collect(b) AS excluded
MATCH (m:MyNode {prop: 'value'})
WITH excluded, COLLECT(m) AS superset
UNWIND [n IN superset WHERE NOT n IN excluded] AS t
WITH t, COUNT(DISTINCT(t.propThree)) AS num
WHERE num > 1
RETURN t.propTwo, num
不幸的是,这不返回任何记录。我发现这可能是因为t值在最终的WITH子句中一次取一个(所以COUNT(DISTINCT(t.propThree))始终为1),但是我不知道如何克服该问题。
答案 0 :(得分:2)
当您在Cypher中具有聚合函数时,请在SQL中将不属于聚合的任何内容视为group by的一部分。似乎不是要按节点t分组,而是要跨多个节点按属性t.propTwo的值分组。
让我们构建一些示例数据。
UNWIND RANGE(1,20) AS idNum
MERGE (n:MyNode {id:idNum})
SET
n.prop = case when n.id < 18 then 'value' else 'not value' end,
n.propTwo = n.id / 3,
n.propThree = n.id /4
RETURN n
MATCH (n1:MyNode {id:3}), (n2:MyNode {id:19})
MERGE (n1)-[:SOME_RELATIONSHIP]->(o:OtherNode)<-[:SOME_RELATIONSHIP]-(n2)
RETURN *
此查询将找到具有prop =“ value”的MyNodes,并为我们提供propTwo的值以及propThree的多个不同值。
MATCH (m:MyNode {prop:"value"})
WITH m.propTwo AS propTwo, COUNT(DISTINCT m.propThree) AS num
WHERE num > 1
RETURN propTwo, num
你应该回来
propTwo num
------- ---
1 2
2 2
5 2
现在,我们使查询更简单一些,以检查模式(m)-[:SOME_RELATIONSHIP]->()<-[:SOME_RELATIONSHIP]-(a:MyNode)
。如果有任何(a)
的道具不等于“值”,则我们要排除(m)
。
MATCH (m:MyNode {prop: 'value'})
OPTIONAL MATCH (m)-[:SOME_RELATIONSHIP]->()<-[:SOME_RELATIONSHIP]-(a:MyNode)
WITH m, SUM(CASE WHEN a IS NULL OR a.prop = 'value' then 0 else 1 end) AS exclude
WHERE exclude = 0
WITH m.propTwo AS propTwo, COUNT(DISTINCT(m.propThree)) AS num
WHERE num > 1
RETURN propTwo, num
你应该回来
propTwo num
------- ---
2 2
5 2