Aggregating functions like SUM
use the non-aggregated items in the same (WITH
or RETURN
) clause as "grouping keys". So, your WITH
clause is generating a SommeUnits
value for each distinct SommeUnits/ReordLevel
combination. And your CREATE
is being called for each SommeUnits
value.
This query should work properly (assuming that you want every returned record to have the same SommeUnits
value):
MATCH(p:Product) WHERE p.productName <> "TotalReord"
WITH SUM(p.unitsInStock) AS SommeUnits, COLLECT(p) AS ps
MERGE(t:Product {productName: "TotalReord"})
SET t.unitsInStock = SommeUnits
WITH ps, SommeUnits
UNWIND ps AS p
RETURN p.reorderLevel AS ReordLevel, p.supplierID AS Supplier, SommeUnits
ORDER BY ReordLevel
This query uses MERGE
to avoid creating duplicate "TotalReord" nodes every time you call this query. And the WHERE
clause filters out the "TotalReord" node, so that its existing unitsInStock
value will not be used when calculating the new sum, inflating it.
If you actually want each returned record to have the sum just for that record's SommeUnits/ReordLevel
combination, you can do this:
MATCH(p:Product) WHERE p.productName <> "TotalReord"
WITH SUM(p.unitsInStock) AS u, p.reorderLevel AS r, p.supplierID AS s
WITH COLLECT({u:u, r:r, s:s}) AS data, SUM(u) AS total
MERGE(t:Product {productName: "TotalReord"})
SET t.unitsInStock = total
WITH data
UNWIND data AS d
RETURN d.r AS ReordLevel, d.s AS Supplier, d.u AS SommeUnits
ORDER BY ReordLevel
[UPDATED]
Finally, if you want to do the previous query but also get the overall total, this query will show the overall total as the fourth value in each returned record:
MATCH(p:Product) WHERE p.productName <> "TotalReord"
WITH SUM(p.unitsInStock) AS u, p.reorderLevel AS r, p.supplierID AS s
WITH COLLECT({u:u, r:r, s:s}) AS data, SUM(u) AS total
MERGE(t:Product {productName: "TotalReord"})
SET t.unitsInStock = total
WITH data, total
UNWIND data AS d
RETURN d.r AS ReordLevel, d.s AS Supplier, d.u AS SommeUnits, total
ORDER BY ReordLevel