> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.nvidia.com/sdgm/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.nvidia.com/sdgm/_mcp/server.

# Write Predictive Queries

> Translate a business question into a complete, testable Kumo Relational PQL query

This tutorial turns a business question into a complete PQL query and tests the query on a small set of entities before scaling up.

## Example question

> How much will each customer spend during the next 30 days?

Assume the graph contains `customers(customer_id, ...)` and `orders(order_id, customer_id, amount, order_time)`.

## 1. Choose the entity

The result should contain one prediction for each customer. Therefore the entity is identified by the `customers.customer_id` primary key.

```text
FOR EACH customers.customer_id
```

## 2. Define the target and horizon

The target is the sum of future order amounts. The interval `0, 30, days` starts at the prediction anchor time and ends 30 days later.

```text
PREDICT SUM(orders.amount, 0, 30, days)
```

## 3. Start with explicit entities

Combine the two parts into a complete query for a few known entity IDs:

```sql
PREDICT SUM(orders.amount, 0, 30, days)
FOR customers.customer_id IN (101, 102, 103)
```

Start without filters. This approach helps isolate errors in the target, graph relationships, and entity selection.

Use backticks around identifiers that contain spaces, punctuation, a leading digit, or another character the PQL grammar cannot express as a bare name. Quote the table and column separately:

```sql
PREDICT SUM(`Order Lines`.`Line Total`, 0, 30, days)
FOR EACH `My Customers`.`Customer ID`
```

Backticks are identifier delimiters; string values continue to use single quotes. Quote each identifier segment independently, leaving the dot between the table and column outside the backticks.

## 4. Submit and inspect

```python
from kumo_relational_client import RelationalClient

query = """
PREDICT SUM(orders.amount, 0, 30, days)
FOR customers.customer_id IN (101, 102, 103)
"""

with RelationalClient(url="http://localhost:8000") as client:
    result = client.relational(graph).predict(query, run_mode="fast")

print(result[["ENTITY", "PREDICTION"]])
```

Confirm that every expected entity appears and that `PREDICTION` contains values of the expected numeric type.

## 5. Add context filters carefully

Use `WHERE` to restrict historical context, not to choose which entities receive predictions. Current Kumo Relational static filters are limited to columns in the same table.

```sql
PREDICT SUM(orders.amount, 0, 30, days)
FOR customers.customer_id IN (101, 102, 103)
WHERE COUNT(orders.*, -90, 0, days) > 0
```

Compare the filtered and unfiltered results for the same entity set. If a query fails, remove the optional clauses and add them back one at a time.

## 6. Scale the entity list

Use `FOR EACH` in PQL and pass IDs by using the `indices` parameter:

```python
with RelationalClient(url="http://localhost:8000") as client:
    result = client.relational(graph).predict(
        "PREDICT SUM(orders.amount, 0, 30, days) "
        "FOR EACH customers.customer_id",
        indices=customer_ids[:1000],
        run_mode="fast",
    )
```

Use [Batch Prediction](/rfm/batch-prediction) when the job exceeds the 1,000-ID request limit.

## Review checklist

* The entity column is a validated primary key.
* The target table is connected to the entity table.
* Temporal targets use the intended future window and unit.
* Context filters do not leak events after the anchor time.
* The first request uses a small, known entity set.
* Results are joined to downstream data by `ENTITY`, never by row position.

See [Prediction Types](/rfm/prediction-types) and [Filters and Operators](/rfm/filters-and-operators).