@@ -20,21 +20,27 @@ The result of a List Subquery is the list formed by collecting all of the values
2020
2121[source, ebnf]
2222----
23+ Atom = ... | ListSubquery | ScalarSubquery ;
24+
2325ListSubquery = '[', SingleValueSubquery, ']' ;
2426
2527ScalarSubquery = 'SCALAR', '(', SingleValueSubquery, ')' ;
2628
2729SingleValueSubquery = SingleValuePatternQuery
2830 | SingleValueUnwindQuery
31+ | SingleValueCallQuery
2932 | SingleValueQuery
3033 ;
3134
32- SingleValuePatternQuery = PatternPart, Filter, SingleValueReturn ;
33- SingleValueUnwindQuery = 'UNWIND', Expression, ['AS', Variable, Filter] ;
34- SingleValueQuery = {{Match | Unwind | Call}-, {With}}-, SingleValueReturn ;
35+ SingleValuePatternQuery = PatternPart, [Where], SingleValueReturn ;
36+ SingleValueUnwindQuery = 'UNWIND', Expression,
37+ ['AS', Variable, [Where], Filter] ;
38+ SingleValueCallQuery = 'CALL', ExplicitProcedureInvocation,
39+ 'YIELD', YieldItem, [Where], Filter ;
40+ SingleValueQuery = {{Match | Unwind | Call}-, {With}}-, SingleValueReturn ;
3541SingleValueReturn = 'RETURN', (Expression | ProjectedMap | Aggregation), Filter ;
3642
37- Filter = [Where], [ Order], [Skip], [Limit] ;
43+ Filter = [Order], [Skip], [Limit] ;
3844----
3945
4046=== Scalar Subqueries
@@ -54,6 +60,17 @@ RETURN [
5460] AS small_items
5561----
5662
63+ [source, cypher]
64+ .Sort an existing list
65+ ----
66+ ...
67+ RETURN [
68+ UNWIND existing_list_of_items AS item
69+ RETURN item
70+ ORDER BY item.price
71+ ] AS small_items
72+ ----
73+
5774[source, cypher]
5875.Collect separate lists of friends and enemies
5976----
@@ -66,3 +83,67 @@ RETURN me.name, [
6683 RETURN enemy.name
6784] AS enemies
6885----
86+
87+ [source, cypher]
88+ .Unpack the value of a singleton list (or fail if the list is not a singleton)
89+ ----
90+ ...
91+ RETURN SCALAR (UNWIND list_with_single_item) AS the_item
92+ ----
93+
94+ [source, cypher]
95+ .Unpack the single element matching a predicate from a list
96+ ----
97+ ...
98+ RETURN SCALAR (
99+ UNWIND existing_list_of_items AS item
100+ WHERE item.name = "Cabbage"
101+ // RETURN is not needed from an UNWIND subquery
102+ ) AS the_item
103+ ----
104+
105+ [source, cypher]
106+ .Unpack the _first_ element matching a predicate from a list
107+ ----
108+ ...
109+ RETURN SCALAR (
110+ UNWIND existing_list_of_items AS item
111+ WHERE item.name CONTAINS "Sweet"
112+ // RETURN is not needed from an UNWIND subquery
113+ LIMIT 1
114+ ) AS first_item
115+ ----
116+
117+ [source, cypher]
118+ .Compute an aggregation of all items in a list
119+ ----
120+ ...
121+ RETURN SCALAR (
122+ UNWIND existing_list_of_items AS item
123+ RETURN avg(item.price)
124+ ) AS avg_item_price
125+ ----
126+
127+ [source, cypher]
128+ .Compute an aggregation over a sub-pattern
129+ ----
130+ MATCH (who:Employee)
131+ RETURN who.name, SCALAR (
132+ MATCH (who)-[filing:FILED]->(receipt)
133+ WHERE date.truncate('month', date() - duration('P1M'))
134+ <= filing.date <
135+ date.truncate('month', date() - duration('P1M'))
136+ RETURN sum(receipt.amount)
137+ ) AS total_expenses
138+ ----
139+
140+
141+ [source, cypher]
142+ .Something
143+ ----
144+ RETURN [
145+ CALL my.cool.Procedure() YIELD theValue
146+ WHERE theValue.temperatureC < 4.0
147+ // Return is not needed for CALL subquery with only a single YIELD field
148+ ] AS all_cool_values
149+ ----
0 commit comments