如何在Neo4j cypher中“压扁”结果?

时间:2015-12-28 07:20:10

标签: neo4j

我有以下表格(类似于Northwind示例数据库):

unravel

对于每个员工,我正在尝试显示员工的订单和$$;即OrderId,SoldAmt 员工的经理上线。

员工和OrderId的组合应该有一条SINGLE行,但到目前为止,我只能显示多行;对于每个级别 - 添加具有经理姓名的附加行。

这是我的密码 *

Employee->OrdersWithDetails<-Products tables
Employee(includes employee-manager relationship with 4 levels)
Employee->EmployeeLvls - links employee's level with specific attributes tied to his level
OrdersWithDetails combines Orders & OrderDetails into one set.

*

这是我的结果: current result

 MATCH (e:Employees)-[:JOB_LEVEL_OF]->(el:EmployeeLvls)
where e.Name ="Vidur Luthra" //limiting to a single employee
MATCH (p:Products)-[:PRODUCT]->(owd:OrdersWithDetails)<-[:SOLD]-(e)-[:REPORTS_TO*0..4]->(m:Employees)-[:JOB_LEVEL_OF]->(el_m:EmployeeLvls)
WHERE m.EmployeeId <> e.EmployeeId  //excluding employee
RETURN e.Name as Employee ,owd.OrderId 
,SUM(owd.ProductQuantity*p.UnitPrice) as SoldAmt //display manager's names based on their level:
,(CASE WHEN m.EmployeeLvlId = e.EmployeeLvlId - 1 THEN m.Name ELSE '-' END) as Manager_1_LevelAbove
,(CASE WHEN m.EmployeeLvlId = e.EmployeeLvlId - 2 THEN m.Name ELSE '-' END) as Manager_2_LevelsAbove
,(CASE WHEN m.EmployeeLvlId = e.EmployeeLvlId - 3 THEN m.Name ELSE '-' END) as Manager_3_LevelsAbove

这是我想要的结果: desired result

Employee|OrderId|SoldAmt |Manager_1_LevelAbove|Manager_2_LevelsAbove| Manager_3_LevelsAbove
Vidur Luthra|94 |733.49  |James Kramer        |                     | 
Vidur Luthra|94 |733.49  |                    |                     | Ken Sanchez
Vidur Luthra|94 |733.49  |                    |Jossef Goldberg      | 

我该怎么办?

2 个答案:

答案 0 :(得分:1)

我认为最好的方法是为你关心的路径部分定义一个变量,然后使用该路径:

MATCH
  (e:Employees)-[:JOB_LEVEL_OF]->(el:EmployeeLvls)
WHERE e.Name ="Vidur Luthra" //limiting to a single employee
MATCH
  (p:Products)-[:PRODUCT]->(owd:OrdersWithDetails)<-[:SOLD]-(e),
  reporting_path=(e)-[:REPORTS_TO*0..4]->(m:Employees)
  (m)-[:JOB_LEVEL_OF]->(el_m:EmployeeLvls)
WHERE
  NOT((m)-[:REPORTS_TO]->()) AND
  m.EmployeeId <> e.EmployeeId  //excluding employee
RETURN
  e.Name as Employee,
  owd.OrderId,
  SUM(owd.ProductQuantity * p.UnitPrice) as SoldAmt,
  (nodes(reporting_path)[0]).Name AS Manager_1_LevelAbove,
  (nodes(reporting_path)[1]).Name AS Manager_2_LevelAbove,
  (nodes(reporting_path)[2]).Name AS Manager_3_LevelAbove

请注意,我为WHERE添加了NOT((m)-[:REPORTS_TO]->())条款。这意味着,如果Jim向Sally报告,他向Bill和Bill报告没有人报告,我们只会在Jim和Bill之间的路上MATCH,而不是Jim和Sally之间的路径。这样我们就不会像你看到的那样重复。

答案 1 :(得分:0)

解决你的评论的另一个答案:

MATCH
  (e:Employees)-[:JOB_LEVEL_OF]->(el:EmployeeLvls)
WHERE e.Name ="Vidur Luthra" //limiting to a single employee
MATCH
  (p:Products)-[:PRODUCT]->(owd:OrdersWithDetails)<-[:SOLD]-(e),
  reporting_path=(e)-[:REPORTS_TO*0..4]->(m:Employees)
WHERE
  NOT((m)-[:REPORTS_TO]->()) AND
  m.EmployeeId <> e.EmployeeId  //excluding employee


WITH e, owd, p, nodes(reporting_path) AS managers
UNWIND managers AS manager
MATCH (manager)-[:JOB_LEVEL_OF]->(el_m:EmployeeLvls)

WITH e, owd, p, collect({Name: manager.Name, JobTitle: el_m.JobTitle}) AS managers

RETURN
  e.Name as Employee,
  owd.OrderId,
  SUM(owd.ProductQuantity * p.UnitPrice) as SoldAmt,
  (managers[0]).Name AS Manager_1_LevelAbove,
  (managers[0]).JobTitle AS Manager_1_JobTitle,
  (managers[1]).Name AS Manager_2_LevelAbove,
  (managers[1]).JobTitle AS Manager_2_JobTitle,
  (managers[2]).Name AS Manager_3_LevelAbove
  (managers[2]).JobTitle AS Manager_3_JobTitle