简体   繁体   English

在 Neo4J 中使用 Cypher 连接两个子查询

[英]Joining two subqueries with Cypher in Neo4J

I have a following SQL query:我有以下 SQL 查询:

SELECT q1.customerId, q1.invoiceId, q2.workId, sum(q2.price)
FROM (select customer.id as customerId, invoice.id as invoiceId, work.id as workId from customer, invoice, workinvoice, work where customer.id=invoice.customerid and invoice.id=workinvoice.invoiceId and workinvoice.workId=work.id
) as q1, (select work.id as workId, sum((price * hours * workhours.discount) + (purchaseprice * amount * useditem.discount)) as price from worktype,workhours,work,warehouseitem,useditem where worktype.id=workhours.worktypeid and workhours.workid=work.id and work.id=useditem.workid and useditem.warehouseitemid=warehouseitem.id group by work.id
) as q2
WHERE q1.workId = q2.workId group by q1.invoiceId;

This query should return me a sum of work prices for each invoice per customer.此查询应返回每个客户每张发票的工作价格总和。

I would be interested to know how to do this kind of query in Neo4J.我很想知道如何在 Neo4J 中进行这种查询。 I know that there is UNION https://neo4j.com/docs/cypher-manual/current/clauses/union/ .我知道有 UNION https://neo4j.com/docs/cypher-manual/current/clauses/union/ However that does seem to do what I want.但是,这似乎确实符合我的要求。 I need to make two subqueries and join them from same node as in that SQL example.我需要创建两个子查询并从与该 SQL 示例中相同的节点加入它们。 What would be the correct way to do this with Cypher?使用 Cypher 执行此操作的正确方法是什么?

There's a quite complex example of how to do a join in cypher which you can find here: https://github.com/moxious/halin/blob/master/src/api/data/queries/dbms/3.5/tasks.js#L22有一个非常复杂的示例,说明如何在 cypher 中进行连接,您可以在这里找到: https : //github.com/moxious/halin/blob/master/src/api/data/queries/dbms/3.5/tasks.js #L22

Basically, the technique is that you run the first query, collect the results.基本上,该技术是您运行第一个查询,收集结果。 Then you run the second, collect the results.然后你运行第二个,收集结果。 Then you unwind the second, match using a filter, and return the result.然后展开第二个,使用过滤器匹配,并返回结果。

In really simplified form, it looks something like this:在真正简化的形式中,它看起来像这样:

CALL something() YIELD a, b
WITH collect({ a: a, b: b }) as resultSet1
CALL somethingElse YIELD a, c
WITH resultSet1, collect({ a: a, c: c }) as resultSet2

UNWIND resultSet2 as rec
WITH [item in resultSet1 WHERE item.a = rec.a][0] as match, rec

RETURN match.a, match.b, rec.c

The list comprehension bit is basically doing the join.列表理解位基本上是在做连接。 Here we're joining on the "a" field.在这里,我们加入了“a”领域。

I figured out the solution I wanted:我想出了我想要的解决方案:

MATCH (inv:invoice)-[:WORK_INVOICE]->(w:work)<-[h:WORKHOURS]-(wt:worktype) WITH inv, w, SUM(wt.price * h.hours * h.discount) as workTimePrice OPTIONAL MATCH (w)-[u:USED_ITEM]->(i:item) WITH inv, workTimePrice + SUM(u.amount * u.discount * i.purchaseprice) as workItemPrice RETURN inv, sum(workItemPrice) as invoicePrice MATCH (inv:invoice)-[:WORK_INVOICE]->(w:work)<-[h:WORKHOURS]-(wt:worktype) WITH inv, w, SUM(wt.price * h.hours * h.discount)作为 workTimePrice OPTIONAL MATCH (w)-[u:USED_ITEM]->(i:item) WITH inv, workTimePrice + SUM(u.amount * u.discount * i.purchaseprice) as workItemPrice RETURN inv, sum(workItemPrice) as invoicePrice

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM