Docs /SQL Editor /Graph queries
SQL EditorGQL

Graph queries

BigQuery property graphs let you write a JOIN chain as a pattern of nodes and edges in GQL. Querylab.io completes labels and properties from your graph's schema, converts JOIN queries to GRAPH_TABLE and back, and draws node-edge results in a Graph tab.

Query 1 · GQL
1234
GRAPH FinGraph
MATCH (sender:Person)-[t:Transfers]->(receiver:Person)
FILTER t.amount > 500
RETURN sender.name AS sender, receiver.name AS receiver, t.amount

The query above is the same as this JOIN, and both return the same rows:

the same query as JOINs
12345
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 is BigQuery’s own syntax: a standalone GRAPH … MATCH … RETURN query, GRAPH_TABLE(…) as a table source inside SQL, and CREATE PROPERTY GRAPH to define a graph. All three get highlighting, completions, hover and checks in the editor. For the language itself, see Google’s GQL reference.

Defining a graph

CREATE PROPERTY GRAPH names the node and edge tables, their keys, labels, and which columns are exposed as properties. The editor checks the statement as you type: an edge table without both SOURCE KEY and DESTINATION KEY, or a graph without NODE TABLES, gets an error squiggle.

123456789101112131415
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)
);

Graphs you’ve created show in the schema tree under their dataset. Opening one gives a details tab with the DDL, node and edge tables, labels, and a connectivity summary.

Inside PROPERTIES (…), typing M offers a MEASURE(…) snippet per allowed aggregate (SUM, AVG, COUNT, MIN, MAX); anything else inside MEASURE() is an error. Inside SELECT … FROM GRAPH_EXPAND("g") the column list is the graph’s Label_column names.

Converting JOINs to GQL and back

Two code actions, in the right-click menu and the quick-fix lightbulb. Both need the graph’s schema, which Querylab.io reads from your project.

  • Convert to GQL GRAPH_TABLE syntax is offered on a SELECT with at least one JOIN whose tables are node or edge tables of a known graph.
  • Convert GRAPH_TABLE to standard SQL JOIN is offered with the cursor inside a GRAPH_TABLE(…), or a standalone GRAPH … query.
before
1234567
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
ORDER BY t.amount DESC
LIMIT 100
after
12345678
SELECT * FROM GRAPH_TABLE(
FinGraph
MATCH (p1:Person)-[t:Transfers]->(p2:Person)
WHERE t.amount > 500
RETURN p1.name AS sender, p2.name AS receiver, t.amount
ORDER BY t.amount DESC
LIMIT 100
)
SQLGQL
FROM t1 JOIN t2 ON …MATCH (n1)-[e]->(n2)
LEFT JOIN / FULL OUTER JOINOPTIONAL MATCH
WHERE condWHERE / FILTER cond
SELECT col AS aliasRETURN col AS alias
ORDER BY, LIMIT, OFFSETCarried through

Set operations, subqueries and PIVOT in the FROM clause, and CTEs other than a recursive path CTE don’t convert; the action isn’t offered. GQL → SQL keeps any trailing WHERE, ORDER BY, LIMIT, OFFSET unchanged.

The same converter, with an editable schema DDL, runs without an account at querylab.io/tools/gql-to-sql.

Completing keywords, labels, and properties

Keyword completions follow the statement: after GRAPH name you get MATCH; after a MATCH, the statements that can follow it; inside () and [] the label separator; after RETURN or FILTER the pattern variables.

With Settings → Editor → SQL Editor → Enable Graph Schema Completions on (off by default), labels complete after the colon and properties after a variable’s dot. Completions work without a reservation. Running a graph query needs an Enterprise or Enterprise Plus reservation.

123
GRAPH FinGraph
MATCH (p:Person)-[t:Transfers]->(q:Person)
RETURN p.
id INT64
name STRING
age INT64

Viewing results as a graph

When a result column holds graph nodes or edges (TO_JSON(n) on a pattern variable), the result panel adds Mode: Graph next to Table and Json.

123456
SELECT TO_JSON(n) AS node, TO_JSON(e) AS edge, TO_JSON(m) AS target
FROM GRAPH_TABLE(
FinGraph
MATCH (n:Person)-[e:Transfers]->(m:Person)
RETURN n, e, m
)
results → Mode: Graph

Transfers

Transfers

PersonAlexid: 1age: 34PersonDanaid: 3age: 29PersonLeeid: 5age: 41
Each card is a node: label, its identifying value, and up to three properties; click a node to see all of them. Edges carry their label on the line.

Drag nodes to rearrange, scroll to zoom, drag the background to pan. Zoom and fit-to-view controls sit bottom-left; larger graphs get a minimap bottom-right.