Skip to content

Commit 10b4dce

Browse files
committed
updated wording in a few places, revisited queries
1 parent d23b153 commit 10b4dce

File tree

1 file changed

+91
-65
lines changed

1 file changed

+91
-65
lines changed

modules/ROOT/pages/queries/composed-queries/sequential-queries.adoc

Lines changed: 91 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -142,20 +142,17 @@ RETURN customer.firstName AS chocolateCustomer,
142142
|===
143143
====
144144

145-
146-
147145
[NOTE]
148146
====
149-
Expressions in a `RETURN` clause must be aliased with an `AS` or a `LET` when they are followed by a `NEXT` clause.
147+
When followed by a `NEXT` clause, expressions in a `RETURN` clause must either be variables that have been introduced before or they must be aliased with `AS`.
150148
====
151149

152-
// is an example necessary? not a fan of negative examples in general
153-
154150

155151
== Interactions with `CALL` subqueries and `WITH`
156152

157153
You can use `NEXT` to rewrite queries containing `CALL` subqueries or a `WITH` clause.
158154

155+
[[call-subquery-rewrite]]
159156
.Rewriting a query with a `CALL` subquery
160157
====
161158
[cols="1,1"]
@@ -164,46 +161,49 @@ a|
164161
.`CALL` subquery
165162
[source, cypher]
166163
----
167-
LET a = 1
168-
WITH a
169-
170-
CALL(*) {
171-
LET b = a + 1
172-
RETURN b
173-
UNION
174-
LET b = a + 2
175-
RETURN b
164+
MATCH (p:Product)
165+
CALL (p) {
166+
MATCH (c:Customer)-[:BUYS]->(p)
167+
RETURN collect(c.firstName) AS customers
176168
}
177-
WITH a, b
178-
179-
LET c = b + 1
180-
RETURN a, b, c
169+
RETURN p.name as product, customers
181170
----
182171
a|
183172
.`NEXT`
184173
[source, cypher]
185174
----
186-
LET a = 1
187-
RETURN a
175+
MATCH (p:Product)
176+
RETURN p
188177
189-
NEXT
178+
NEXT
190179
191-
LET b = a + 1
192-
RETURN a, b
193-
UNION
194-
LET b = a + 2
195-
RETURN a, b
180+
MATCH (c:Customer)-[:BUYS]->(p)
181+
RETURN collect(c.firstName) AS customers, p
196182
197-
NEXT
183+
NEXT
198184
199-
LET c = b + 1
200-
RETURN a, b, c
185+
RETURN p.name as product, customers
201186
----
202187
|===
203-
====
204188
189+
.Result
190+
[role="queryresult",options="header,footer",cols="2*<m"]
191+
|===
192+
| product | customers
193+
194+
| "Laptop" | ["Amir", "Mateo", "Leila", "Yusuf"]
195+
| "Phone" | ["Niko"]
196+
| "Headphones" | ["Keisha", "Hannah", "Niko"]
197+
| "Chocolate" | ["Amir", "Mateo", "Yusuf"]
198+
| "Coffee" | ["Mateo", "Hannah", "Niko"]
199+
2+d|Rows: 5
200+
|===
201+
====
205202

203+
Even though the `NEXT` query in <<call-subquery-rewrite>> has more lines, it is divided into three segments which are easy to read.
204+
It also avoids the parentheses and indentation of the `CALL` subquery.
206205

206+
[[with-rewrite]]
207207
.Rewriting a `WITH` query
208208
====
209209
[cols="1,1"]
@@ -246,80 +246,106 @@ RETURN d
246246
|===
247247
====
248248

249-
Variables which are local to a query and which are not explicitly returned are not accessible by its subsequent query in the context of `NEXT`.
250-
This allows you to control variable scope similarly to what you can do with `WITH`, see xref:clauses/with.adoc#variable-scope[Control variables in scope].
249+
250+
Variables which are local to a query and which are not explicitly returned are not accessible by subsequent queries in the context of `NEXT`.
251+
This allows you to control variable scope similarly to what you can do with `WITH`, see xref:clauses/with.adoc#variable-scope[Control variables in scope]: in <<with-rewrite>>, each occurrence of `WITH` is replaced by a `RETURN` and a `NEXT`, preserving the variable scope.
251252

252253
[NOTE]
253254
====
254255
`NEXT` cannot be used inside a `CALL` subquery that uses the (deprecated) xref:subqueries/call-subquery.adoc#importing-with[importing `WITH`] syntax.
255256
====
256257

257-
== Interactions with conditional queries
258258

259-
// use example with the example data set instead
259+
== Interactions with conditional queries
260260

261+
[[next-and-conditional]]
261262
.`NEXT` in a conditional query
262263
====
263264
.Query
264265
[source, cypher]
265266
----
266-
MATCH (n)
267-
RETURN n
267+
MATCH (c:Customer)-[:BUYS]->(:Product)<-[:SUPPLIES]-(s:Supplier)
268+
RETURN c.firstName AS customer, s.name AS supplier
268269
269-
NEXT
270+
NEXT
270271
271-
WHEN n.x > 2 THEN
272-
RETURN "large number" AS msg
273-
WHEN n.x > 1 THEN
274-
RETURN "small number" AS msg
275-
ELSE
276-
RETURN "tiny number" AS msg
272+
WHEN supplier = "TechCorp" THEN
273+
RETURN customer, "Tech enjoyer" AS personality
274+
WHEN supplier = "Foodies Inc." THEN
275+
RETURN customer, "Tropical plant enjoyer" AS personality
276+
277+
NEXT
277278
279+
RETURN customer, collect(DISTINCT personality) AS personalities
280+
281+
NEXT
282+
283+
WHEN size(personalities) > 1 THEN
284+
RETURN customer, "Enjoyer of tech and plants" AS personality
285+
ELSE
286+
RETURN customer, personalities[0] AS personality
278287
----
279288
280289
.Result
281-
[role="queryresult",options="header,footer",cols="1*<m"]
290+
[role="queryresult",options="header,footer",cols="2*<m"]
282291
|===
283-
| chocolateCustomer
292+
| customer | personality
284293
285-
| "Amir"
286-
| "Mateo"
287-
| "Yusuf"
294+
| "Amir" | "Enjoyer of tech and plants"
295+
| "Mateo" | "Enjoyer of tech and plants"
296+
| "Yusuf" | "Enjoyer of tech and plants"
297+
| "Niko" | "Enjoyer of tech and plants"
298+
| "Hannah" | "Enjoyer of tech and plants"
299+
| "Leila" | "Tech enjoyer"
300+
| "Keisha" | "Tech enjoyer"
288301
289-
1+d|Rows: 3
302+
2+d|Rows: 7
290303
|===
291304
====
292305

306+
In <<next-and-conditional>>, customers are assigned personality types based on the products they purchased.
307+
The second query is a conditional query that returns different base personality types for different suppliers the customers purchased from.
308+
The third query aggregates the personality types.
309+
Finally, the fourth query is another conditional query which subsumes multiple base personality types, if present, to a new personality.
293310

294-
== Interactions with `UNION` queries
295311

296-
// use example with the example data set instead
312+
== Interactions with `UNION` queries
297313

314+
[[next-and-union]]
298315
.`NEXT` in a query using `UNION`
299316
====
300317
.Query
301318
[source, cypher]
302319
----
303-
RETURN 1 AS a
304-
UNION
305-
RETURN 2 AS a
320+
MATCH (c:Customer)-[:BUYS]->(:Product{name: "Laptop"})
321+
RETURN c.firstName AS customer
322+
UNION ALL
323+
MATCH (c:Customer)-[:BUYS]-> (:Product{name: "Coffee"})
324+
RETURN c.firstName AS customer
306325
307-
NEXT
326+
NEXT
308327
309-
RETURN a, a + 1 AS b
310-
UNION
311-
RETURN a, a + 2 AS b
328+
RETURN customer AS customer, count(customer) as numberOfProducts
312329
----
313330
314331
.Result
315-
[role="queryresult",options="header,footer",cols="1*<m"]
332+
[role="queryresult",options="header,footer",cols="2*<m"]
316333
|===
317-
| chocolateCustomer
334+
| customer | numberOfProducts
318335
319-
| "Amir"
320-
| "Mateo"
321-
| "Yusuf"
336+
| "Amir" | 1
337+
| "Mateo" | 2
338+
| "Leila" | 1
339+
| "Yusuf" | 1
340+
| "Hannah" | 1
341+
| "Niko" | 1
322342
323-
1+d|Rows: 3
343+
344+
2+d|Rows: 6
324345
|===
325-
====
346+
====
347+
348+
In <<next-and-union>>, the list of customer names from the first query has a duplicate entry for "Mateo" who bought both a laptop and coffee.
349+
The use of `UNION ALL` added him to the list twice.
350+
The second query can access the list, because both parts of the `UNION` return a part of the list, aliased as `customer`.
351+
By using `count()`, the list aggregates the duplicate in the `RETURN` part of the query.

0 commit comments

Comments
 (0)