Querying with GRAPH_TABLE and MATCH

Applies to: ✅ Data 360 SQL ✅ Tableau Hyper API

After you define the graph, GRAPH_TABLE finds matching paths and returns them as a table. Use it in FROM like any other table.

The examples on this page show the GRAPH_TABLE portion. Keep the WITH ... AS PROPERTY GRAPH definition in the same statement.

1WITH <graph_name> AS PROPERTY GRAPH (...)
2SELECT ...
3FROM GRAPH_TABLE ( <graph_name>
4    MATCH <pattern>
5    [ WHERE <condition> ]
6    [ ONE ROW PER MATCH
7    | ONE ROW PER STEP ( <src_var>, <edge_var>, <dst_var> ) ]
8    [ COLUMNS ( <column>[, ...] ) ]
9) [ AS <alias> ]

Write the clauses in that order: MATCH, then WHERE, then the result mode, then COLUMNS.

  • <graph_name> must be the graph you just defined. It can’t be a Data 360 object, ordinary table, or view. Catalog property graphs aren’t supported.
  • If you include COLUMNS, add a table alias (like AS gt).
  • If you omit COLUMNS, every bound variable’s properties become output columns, in pattern order.

MATCH: Describe the Path 

MATCH is the pattern you want to find. Parentheses are vertices. Dashes are edges. See Path Patterns and Quantifiers for more on direction and hops.

  • -[]-> walks from left to right.
  • <-[]- walks from right to left.
  • -[]- walks either way.
1MATCH (i:individual)-[:customerOrder]->(order:salesOrder)

That means: bind the variable i to vertices with the individual label, follow a customerOrder edge, and bind order to the destination vertex with the salesOrder label.

Build a pattern in this order.

  1. () matches any vertex.
  2. ()-[]->() matches any two vertices connected by a rightward edge. Use <-[]- for left and -[]- for either way.
  3. Add labels: (i:individual)-[:customerOrder]->(order:salesOrder).
  4. Use the bound name to read properties: i.name, order.orderId.
  5. Use a local WHERE to filter that one element: (i:individual WHERE i.name = 'Avery').
  6. Chain more hops to follow a longer path, or separate independent patterns with commas.
1MATCH (i:individual)-[:customerOrder]->(order:salesOrder)   -- one path
2MATCH (i:individual), (product:product)                    -- two separate vertices

How to Read Properties 

When a pattern matches a record, you give that match a name. Then you read its fields through the name.

(i:individual) means: find an Individual and call it i.

i.name means: use the name property on that customer.

The property name is the name from the graph definition. It doesn’t have to match the DMO field name.

In the commerce graph:

ObjectObject fieldUse this in the query
Individualssot__Id__ci.individualId
Individualssot__FirstName__ci.name
Sales Orderssot__Id__corder.orderId
Sales Orderssot__Name__corder.name
Goods Productssot__Id__cproduct.productId
Goods Productssot__Name__cproduct.name
Sales Order Productssot__CreatedDate__cline.createdDate
Sales Order Productssot__OrderedQuantity__cline.quantity

Use those names in WHERE and COLUMNS. Don’t use the raw ssot__... names unless the graph exposed the columns as-is.

WHERE: Filter the Path 

Use an element-local WHERE to filter one customer, order, or line item. Use a global WHERE when the condition compares more than one of them.

This query keeps Avery’s orders that include more than one unit.

1WITH pg AS PROPERTY GRAPH (...)
2SELECT * FROM GRAPH_TABLE(pg
3    MATCH (i:individual)-[:customerOrder]->(:salesOrder)
4        -[line:orderProduct]->(product:product)
5    WHERE i.name = 'Avery' AND line.quantity > 1
6) AS gt;

This version puts each filter next to the vertex or edge it applies to.

1WITH pg AS PROPERTY GRAPH (...)
2SELECT * FROM GRAPH_TABLE(pg
3    MATCH (i:individual WHERE i.name = 'Avery')
4        -[:customerOrder]->(:salesOrder)
5        -[line:orderProduct WHERE line.quantity > 1]->(product:product)
6) AS gt;

A local WHERE needs a bound name, so you can’t attach one to (:product). On a repeated edge, that local filter applies to every hop. A global WHERE runs before COLUMNS, so it can’t use column aliases.

COLUMNS: Choose the Result Fields 

COLUMNS is the result table you want back. Each item is one of these.

1COLUMNS (
2    <variable>.<property> [AS <alias>],
3    <expression> AS <alias>,
4    <variable>.*,
5    <variable>.* EXCLUDE ( <property>[, ...] )
6)
  • variable.property — the alias defaults to the property name.
  • Any SQL expression — AS is required.
  • variable.* — every property on that variable.
  • variable.* EXCLUDE (...) — every property except the ones you list.

Use AS when you rename a column. An alias without AS is a syntax error. The outer SELECT can use only the columns you list.

1WITH pg AS PROPERTY GRAPH (...)
2SELECT gt.individual_name, gt.product_name, gt.ordered_quantity
3FROM GRAPH_TABLE(pg
4    MATCH (i:individual)-[:customerOrder]->(:salesOrder)
5        -[line:orderProduct]->(product:product)
6    COLUMNS (
7        i.name AS individual_name,
8        product.name AS product_name,
9        line.quantity AS ordered_quantity
10    )
11) AS gt;

You can also project every property on a variable with i.*, or hide some of them with i.* EXCLUDE (individualId). If that variable can match more than one element table, the star expands to every property those element tables expose. See Cross-Label Property Access.

Examples 

These examples use the commerce graph from Defining a Property Graph.

Find a Customer 

1WITH pg AS PROPERTY GRAPH (...)
2SELECT gt.individual_name
3FROM GRAPH_TABLE(pg
4    MATCH (i:individual WHERE i.individualId = 'I-1001')
5    COLUMNS (i.name AS individual_name)
6) AS gt;

List Products on an Order 

1WITH pg AS PROPERTY GRAPH (...)
2SELECT gt.individual_name, gt.product_name, gt.createdDate, gt.quantity
3FROM GRAPH_TABLE(pg
4    MATCH (i:individual)-[:customerOrder]->(:salesOrder)
5        -[line:orderProduct]->(product:product)
6    COLUMNS (
7        i.name AS individual_name,
8        product.name AS product_name,
9        line.createdDate,
10        line.quantity
11    )
12) AS gt;

Return Every Property on the Customer 

1WITH pg AS PROPERTY GRAPH (...)
2SELECT gt.*
3FROM GRAPH_TABLE(pg
4    MATCH (i:individual)-[:customerOrder]->(:salesOrder)
5        -[line:orderProduct]->(product:product)
6    COLUMNS (i.*, line.createdDate)
7) AS gt;

Related Documentation