The RETURN statement allows you to specify items to include in the query result. Each item is defined by an expression that can include variables, properties, functions, constants, etc.
Syntax<return statement> ::= "RETURN" [ "DISTINCT" | "ALL" ] { < "*" > | <return items> } [ <group by clause> ] <return items> ::= <return item> [ { "," <return item> }... ] <return item> ::= <value expression> [ "AS" <identifier> ] <group by clause> ::= "GROUP BY" <grouping key> [ { "," <grouping key> }... ] [ <having clause> ] <having clause> ::= "HAVING" <search condition>
Details
* returns all columns in the intermediate result table. See Returning All.AS can be used to rename a return item. See Return Item Alias.RETURN statement supports the GROUP BY clause. See Returning with Grouping.<having clause> can follow GROUP BY to filter groups based on aggregate results. See Filtering Groups with HAVING.DISTINCT operator can be used to deduplicate records. If neither DISTINCT nor ALL is specified, ALL is implicitly applied. See Returning Distinct Records.
GQLINSERT (alex:Student {_id: 's1', name: 'Alex', gender: 'male'}), (susan:Student {_id: 's2', name: 'Susan', gender: 'female'}), (art:Course {_id: 'c1', name: 'Art', credit: 13}), (literature:Course {_id: 'c2', name: 'Literature', credit: 15}), (alex)-[:Take {year: 2024, term: 'Spring'}]->(art), (susan)-[:Take {year: 2023, term: 'Fall'}]->(art), (susan)-[:Take {year: 2023, term: 'Spring'}]->(literature)
A variable bound to nodes returns all information about each node.
GQLMATCH (n:Course) RETURN n
Result:
| _id | label | name | credit |
|---|---|---|---|
| c2 | Course | Literature | 15 |
| c1 | Course | Art | 13 |
A variable bound to edges returns all information about each edge.
GQLMATCH ()-[e]->() RETURN e
Result:
| _id | _from | _to | label | year | term |
|---|---|---|---|---|---|
| e:3 | s2 | c2 | Take | 2023 | Spring |
| e:2 | s2 | c1 | Take | 2023 | Fall |
| e:1 | s1 | c1 | Take | 2024 | Spring |
A variable bound to paths returns all information about the nodes and edges included in each path.
GQLMATCH p = ()-[:Take {term: "Spring"}]->() RETURN p
Result: p

The function labels() can be used to return the labels of nodes and edges.
GQLMATCH ({_id: "s2"})-[e]->(n) RETURN labels(e), labels(n)
Result:
| labels(e) | labels(n) |
|---|---|
| ["Take"] | ["Course"] |
| ["Take"] | ["Course"] |
The period operator . can be used to extract the value of a specified property from a variable bound to nodes or edges. The null value will be returned if the specified property is not found on the nodes or edges.
GQLMATCH (:Student {name:"Susan"})-[]->(c:Course) RETURN c.name, c.credit, c.type
Result:
| c.name | c.credit | c.type |
|---|---|---|
| Literature | 15 | null |
| Art | 13 | null |
The asterisk * returns all columns in the intermediate result table. Note that the RETURN statement cannot include the GROUP BY clause when using *.
GQLMATCH (s:Student {name:"Susan"})-[]->(c:Course) RETURN *
Result:
[ {"id": "s2", "labels": ["Student"], "properties": {"name": "Susan", "gender": "female"}}, {"id": "s2", "labels": ["Student"], "properties": {"name": "Susan", "gender": "female"}}, ]
The AS keyword allows you to assign an alias to a return item.
GQLMATCH (s:Student)-[t:Take]->(c:Course) RETURN s.name AS Student, c.name AS Course, t.year AS TakenIn
Result:
| Student | Course | TakenIn |
|---|---|---|
| Alex | Art | 2024 |
| Susan | Art | 2023 |
| Susan | Literature | 2023 |
The LIMIT statement can be used to restrict the number of records retained for each return item.
GQLMATCH (n:Course) RETURN n.name LIMIT 1
Result:
| n.name |
|---|
| Literature |
The ORDER BY statement can be used to sort the records.
GQLMATCH (n:Course) RETURN n ORDER BY n.credit DESC
Result:
| _id | name | credit |
|---|---|---|
| c2 | Literature | 15 |
| c1 | Art | 13 |
A RETURN item can be any value expression, not only a variable or property reference. The expression is evaluated per row and the result becomes a column in the output. Computed values cover arithmetic, function calls, string concatenation, conditional CASE expressions, comparisons, and any composition of these.
Arithmetic on properties:
GQLMATCH (n:Course) RETURN n.name, n.credit, n.credit * 2 AS double_credit
Result:
| n.name | n.credit | double_credit |
|---|---|---|
| Art | 13 | 26 |
| Literature | 15 | 30 |
Function call on a property:
GQLMATCH (n:Student) RETURN n.name, upper(n.name) AS upper_name
Result:
| n.name | upper_name |
|---|---|
| Alex | ALEX |
| Susan | SUSAN |
GQLMATCH (:Student {name:"Susan"})-[]->(c:Course) RETURN sum(c.credit)
Result:
| sum(c.credit) |
|---|
| 28 |
Comparison and conditional:
GQLMATCH (n:Course) RETURN n.name, CASE WHEN n.credit >= 14 THEN 'high' ELSE 'low' END AS credit_level
Result:
| n.name | credit_level |
|---|---|
| Art | low |
| Literature | high |
The GROUP BY clause allows you to specify the keys to group the query result. After grouping, each group will keep only one record.
GQLMATCH ()-[e:Take]->() RETURN e.term GROUP BY e.term
Result:
| e.term |
|---|
| Spring |
| Fall |
In the GQL standard, the grouping key must be a direct variable reference, where this query must be written as RETURN e.term AS <varName> GROUP BY <varName>. Ultipa simplifies this by allowing direct grouping on expressions, removing the need to introduce intermediate variables.
GQLMATCH ()<-[e:Take]-() RETURN e.year, e.term GROUP BY e.year, e.term
Result:
| e.year | e.term |
|---|---|
| 2023 | Spring |
| 2023 | Fall |
| 2024 | Spring |
When grouping is applied, any aggregation operation in the RETURN statement is performed on each group.
This query counts the number of Take edges for each Term:
GQLMATCH ()-[e:Take]->() RETURN e.term, count(e) GROUP BY e.term
Result:
| e.term | count(e) |
|---|---|
| Spring | 2 |
| Fall | 1 |
The HAVING clause filters groups produced by GROUP BY based on aggregate results. It must follow GROUP BY and is evaluated after grouping and aggregation, allowing the search condition to reference aggregate functions or their aliases.
HAVING differs from WHERE/FILTER: WHERE and FILTER filter records before grouping and cannot reference aggregate results, while HAVING filters groups after aggregation.
This query returns terms in which more than one Take edge exists:
GQLMATCH ()-[e:Take]->() RETURN e.term AS term, count(e) AS cnt GROUP BY e.term HAVING cnt > 1
Result:
| term | cnt |
|---|---|
| Spring | 2 |
This query returns years in which the total credit of taken courses exceeds 20:
GQLMATCH ()-[e:Take]->(c:Course) RETURN e.year AS year, sum(c.credit) AS totalCredit GROUP BY e.year HAVING totalCredit > 20
Result:
| year | totalCredit |
|---|---|
| 2023 | 28 |
The DISTINCT operator deduplicates records for all return items. When DISTINCT is specified, each return item is implicly an operand of a grouping operation.
GQLMATCH ()-[e]->() RETURN DISTINCT e.year
This is equivalent to:
GQLMATCH ()-[e]->() RETURN e.year GROUP BY e.year
Result:
| e.year |
|---|
| 2023 |
| 2024 |
GQLMATCH ()-[e]->() RETURN DISTINCT e.year, e.term
This is equivalent to:
GQLMATCH ()-[e]->() RETURN e.year, e.term GROUP BY e.year, e.term
Result:
| e.year | e.term |
|---|---|
| 2023 | Fall |
| 2023 | Spring |
| 2024 | Spring |