2015-12-28 48 views
2

我有如下表(類似Northwind示例數據庫):如何將Neo4j密碼的結果「變平」?

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. 

對於每一個員工,我想,以顯示僱員的訂單和$$;即OrderId,SoldAmt 員工的經理上線。

員工和OrderId的組合應該有SINGLE行,但到目前爲止我只能顯示多行;爲每個級別添加經理姓名的附加行。

這裏是我的暗號 *

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 

*

這裏是我的結果: current 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  | 

這是我想要的結果: desired result

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

我該怎麼辦?

回答

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]->())。這意味着,如果吉姆向莎莉彙報給比爾和比爾向任何人報告,我們只會在吉姆和比爾之間的路徑MATCH,而不是吉姆和薩莉之間的路徑。這樣我們就不會像你所看到的那樣得到重複。

+0

有可能是一個差一錯誤在這裏,但我認爲,這裏的原則應該是不錯的 –

+0

布萊恩,你的建議,解決了我的問題,但只是理論上實際上,我需要能夠顯示或至少將結果導出爲ex​​cel。從附圖中可以看出,這不是一個理想的結果。 – DanielSF

+0

我不知道我明白。您是否說我的解決方案爲每位員工返回多個結果? –

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 
+0

是的,這是完美的工作。 – DanielSF