Graph Queries
Query property graphs with GQL (Graph Query Language), convert between SQL and GQL, and visualize graph results — all inside Querylab.io.
What are Graph Queries?
BigQuery property graphs let you model data as nodes and edges. Instead of writing multi-table JOINs, you describe traversal patterns:
Standard SQL:
SELECT p1.name AS sender, p2.name AS receiver, t.amount
FROM Person AS p1
JOIN Transfers AS t ON p1.id = t.source_id
JOIN Person AS p2 ON t.dest_id = p2.id
WHERE t.amount > 500
GQL:
GRAPH FinGraph
MATCH (p1:Person)-[t:Transfers]->(p2:Person)
WHERE t.amount > 500
RETURN p1.name AS sender, p2.name AS receiver, t.amount
Both produce the same result — but GQL makes the relationship structure explicit.
GQL Syntax
Node Patterns
Nodes are enclosed in parentheses. You can specify a variable, a label, or both:
(a:Person) -- variable + label
(:Person) -- label only
(a) -- variable only
() -- anonymous node
(a IS Person) -- IS label syntax
(a:Person WHERE a.age > 30) -- inline WHERE
Edge Patterns
Edges connect nodes with direction arrows:
-[t:Transfers]-> -- outgoing edge with variable + label
<-[t:Transfers]- -- incoming edge
-[t:Transfers]- -- undirected edge
-> -- abbreviated outgoing (no variable/label)
<- -- abbreviated incoming
Full Patterns
Chain nodes and edges to describe graph traversals:
-- Person sends a transfer to another person
(a:Person)-[t:Transfers]->(b:Person)
-- Multi-hop: person transfers through an intermediary
(a:Person)-[t1:Transfers]->(mid:Person)-[t2:Transfers]->(b:Person)
-- Multiple separate patterns
(a:Person)-[t:Transfers]->(b:Person), (b)-[o:Owns]->(acc:Account)
Linear Query Structure
A GQL query starts with GRAPH, followed by one or more statements, and ends with RETURN:
GRAPH FinGraph
MATCH (a:Person)-[t:Transfers]->(b:Person)
OPTIONAL MATCH (b)-[o:Owns]->(acc:Account)
FILTER t.amount > 100
LET total = SUM(t.amount)
RETURN a.name AS sender, b.name AS receiver, total
| Statement | Purpose |
|---|---|
MATCH | Required. Define the graph pattern to find |
OPTIONAL MATCH | Like MATCH, but keeps rows with no match |
FILTER / WHERE | Filter matched results |
LET | Bind computed values to variables |
FOR ... IN | Iterate over arrays with optional WITH OFFSET |
RETURN | Required as last statement. Define output columns |
GRAPH_TABLE Syntax
An alternative way to embed GQL inside standard SQL using GRAPH_TABLE:
SELECT *
FROM GRAPH_TABLE(
FinGraph
MATCH (a:Person)-[t:Transfers]->(b:Person)
RETURN a.name AS sender, b.name AS receiver, t.amount
)
WHERE amount > 500
ORDER BY amount DESC
This lets you use GQL as a table expression inside regular SQL — useful for combining graph results with standard operations like ORDER BY, LIMIT, or JOINing with non-graph tables.
Property Graph Schema
A property graph is defined with CREATE PROPERTY GRAPH, declaring which tables are nodes and edges:
CREATE PROPERTY GRAPH FinGraph
NODE TABLES (
Person KEY (id)
LABEL Person PROPERTIES (id, name, age),
Account KEY (id)
LABEL Account PROPERTIES (id, balance)
)
EDGE TABLES (
Transfers KEY (transfer_id)
SOURCE KEY (source_id) REFERENCES Person (id)
DESTINATION KEY (dest_id) REFERENCES Person (id)
LABEL Transfers PROPERTIES (transfer_id, amount, date),
Owns KEY (account_id)
SOURCE KEY (owner_id) REFERENCES Person (id)
DESTINATION KEY (account_id) REFERENCES Account (id)
LABEL Owns PROPERTIES (since)
)
- NODE TABLES — each entry defines a base table, key column, label, and exposed properties
- EDGE TABLES — each entry defines a base table, key column, source/destination references, label, and properties
- Labels — used in MATCH patterns to reference node/edge types
- Properties — columns available via dot notation (e.g.,
a.name)
GQL ↔ SQL Conversion
Convert between standard SQL with JOINs and GQL GRAPH_TABLE syntax.
In the Editor
Right-click (or use the quick-fix lightbulb) on a query to see conversion options:
- "Convert to GQL GRAPH_TABLE syntax" — appears on SELECT statements with at least one JOIN
- "Convert GRAPH_TABLE to standard SQL JOIN" — appears inside GRAPH_TABLE clauses
The converter uses the property graph schema to correctly map:
- FROM/JOIN tables → node and edge labels
- JOIN ON conditions → edge SOURCE/DESTINATION references
- WHERE conditions → FILTER clauses
- SELECT list → RETURN columns
Online Converter
Try the free GQL ↔ SQL Converter — no login required. Paste SQL or GQL, edit the graph schema DDL, and convert in either direction with syntax highlighting.
What Converts
| SQL Pattern | GQL Equivalent |
|---|---|
FROM t1 JOIN t2 ON ... | MATCH (n1)-[e]->(n2) |
LEFT JOIN | OPTIONAL MATCH |
WHERE condition | FILTER condition |
SELECT col AS alias | RETURN col AS alias |
| Multi-JOIN chains | Multi-hop patterns |
Limitations
- Only simple SELECT statements (no CTEs, subqueries, or set operations)
- Requires a property graph schema to map tables to labels
- ORDER BY and LIMIT are stripped during conversion
Graph Result Visualization
When a query returns graph elements, a Graph tab appears automatically in the results panel.
When Does the Graph Tab Appear?
The Graph tab activates when query results contain JSON objects with "kind": "node" or "kind": "edge". This happens when you use BigQuery's TO_JSON() on graph element columns:
SELECT TO_JSON(n) AS node_data, TO_JSON(e) AS edge_data
FROM GRAPH_TABLE(
FinGraph
MATCH (n:Person)-[e:Transfers]->(m:Person)
RETURN n, e, m
)
Interacting with the Graph
- Drag nodes to reposition them
- Click a node to see its identifier
- Scroll to zoom in/out
- Pan by dragging the background
- Use the minimap (bottom-right) for overview navigation
- Use controls (bottom-left) for zoom and fit-to-view
Node Cards
Each node displays:
- Label (e.g., "Person") as the header
- Primary property — the first identifying value (id or name)
- Top properties — up to 3 key-value pairs
- Click to expand and see all properties
Edges show their label on the connecting line between nodes.
IDE Features
Auto-Completions
Context-aware completions inside GQL queries:
- After
GRAPH graph_name→ suggestsMATCH,RETURN,FILTER,OPTIONAL MATCH,LET,FOR,WITH - After
MATCH (pattern)→ suggests next statements - Inside
RETURN→ suggests graph functions and variables - Inside
FILTER→ suggests predicates and operators - Inside node
()and edge[]patterns → suggests label separator:
Diagnostics
Real-time error checking for GQL queries:
| Error | What it Means |
|---|---|
| RETURN must be last statement | GQL linear queries must end with RETURN |
| Missing NODE TABLES | CREATE PROPERTY GRAPH requires at least NODE TABLES |
| Missing SOURCE/DESTINATION KEY | Edge tables must declare both key references |
| Empty RETURN | RETURN must have at least one expression |
Examples
Basic Graph Query
GRAPH FinGraph
MATCH (p:Person)
RETURN p.name, p.age
Find All Transfers Over $500
GRAPH FinGraph
MATCH (sender:Person)-[t:Transfers]->(receiver:Person)
FILTER t.amount > 500
RETURN sender.name, receiver.name, t.amount
Multi-Hop Path
GRAPH FinGraph
MATCH (a:Person)-[t1:Transfers]->(b:Person)-[t2:Transfers]->(c:Person)
RETURN a.name AS origin, c.name AS destination, t1.amount + t2.amount AS total
GRAPH_TABLE with Standard SQL
SELECT sender, SUM(amount) AS total_sent
FROM GRAPH_TABLE(
FinGraph
MATCH (s:Person)-[t:Transfers]->(r:Person)
RETURN s.name AS sender, t.amount AS amount
)
GROUP BY sender
ORDER BY total_sent DESC
LIMIT 10
Graph Visualization Query
To see results in the Graph tab, return graph elements as JSON:
SELECT TO_JSON(n) AS node, TO_JSON(e) AS edge
FROM GRAPH_TABLE(
FinGraph
MATCH (n:Person)-[e:Transfers]->(m:Person)
RETURN n, e, m
)