Following up on last month’s SQL/PGQ introduction, let’s go deeper into the GRAPH_TABLE function — the SQL construct that makes graph traversal queries possible in Oracle 23ai.
GRAPH_TABLE appears in the FROM clause and returns a relational result set from a graph pattern match. This means you can use it exactly like any other table or view — filter it with WHERE, join it with other tables, aggregate it with GROUP BY.
Detecting fraud rings (connected accounts):
SELECT account_id, connected_account, hops
FROM GRAPH_TABLE (
transaction_graph
MATCH (a IS accounts) -[IS transfers]->{2,5} (b IS accounts)
WHERE a.flagged = 1
COLUMNS (
a.account_id,
b.account_id AS connected_account,
GRAPH_PATH_LENGTH() AS hops
)
)
WHERE hops <= 3;
Finding shortest path:
SELECT *
FROM GRAPH_TABLE (
supply_chain_graph
MATCH SHORTEST (supplier) -[IS supplies]->+ (product)
WHERE supplier.country = 'US' AND product.sku = 'SKU-9981'
COLUMNS (LISTAGG(supplier.name, ' -> ') WITHIN GROUP (GRAPH ORDER) AS supply_path)
);
Combining with relational data:
-- Which customers are connected to known fraudsters, and what's their credit limit?
SELECT g.customer_id, c.credit_limit, g.hops
FROM GRAPH_TABLE (
fraud_network_graph
MATCH (seed) -[IS knows]->{1,3} (connected)
WHERE seed.is_fraudster = TRUE
COLUMNS (connected.customer_id, GRAPH_PATH_LENGTH() AS hops)
) g
JOIN customers c ON c.customer_id = g.customer_id
WHERE c.credit_limit > 10000;
The power of GRAPH_TABLE is not graph traversal in isolation — it’s the seamless combination of graph patterns with relational operations. This is what sets Oracle’s implementation apart from standalone graph databases.
