Query Data

Overview

Query Data searches records you've stored earlier, with filtering, sorting, limiting, and statistical aggregation. Use it to find matching records, calculate totals and averages, get the top N results, or run deeper statistics like median and standard deviation.

* Example flow demonstrating how a player's spin result is stored using Save Data, retrieved with Query Data, and processed one record at a time using Loop.

Note: The variable names, values, criteria, and configuration used in this example are for demonstration purposes only.

Where to find it: Actions > Local Storage in the stage library.

Configuration

Required Fields

FieldDescriptionExample
Query typeWhat kind of result to return: a list of records, basic totals, or extended statistics (see Query Types below)All items as array
Group nameThe group holding the data to search, matching the group name used when the data was savedUserScores, {{groupName}}
Output variable nameVariable name to store the query results undertopScores, salesStats

Optional Fields

FieldDescriptionExample
Record nameNarrow the search to records matching this name pattern. Leave blank to search every record in the group. Supports wildcardsuser_*, {{recordPattern}}
filter1Lower bound for value filtering: only include records whose value is greater than or equal to this number. Must be a number or left blank70, {{minScore}}
filter2Upper bound for value filtering: only include records whose value is less than or equal to this number. Must be a number or left blank90, {{maxScore}}
Order bySort direction applied to each record's value before the limit is applied. A direction choice, not a column name: ASC, DESC, or blankDESC
numOfRecordsMaximum number of records to return, applied after sorting10, {{limit}}
Reverse orderReverses the final result set after sorting and limiting have already been applied. Only available when Query type is "All items as array" and Number of records has a valuetrue or false

Order by is a sort direction only: it always sorts on the record's stored value, so it can't be pointed at a different column.

Using functions in these fields: Any value field above accepts @ functions, for example @NowSecond for the current time or @calc(...) for a calculation. 

See Flows Functions for the full list.

Query Types

TypeOutput VariablesSorting, limits, reverse order
All items as array{{variable}}: a list of matching record values✓ Apply; the only type these apply to
Get sum and count etc{{variable}}.sum, .count, .average, .minimum, .maximum✗ Disabled; there are no individual records to sort
Get statistical averagesEverything above, plus .median, .range, .stan_dev, .variance, .q1, .q3, .unique✗ Disabled; there are no individual records to sort

Working With Group Names

PrefixFormatUse
Cachecache(seconds)::groupNameReuse results for a set number of seconds instead of querying again each time

Example: cache(60)::UserScores caches the query's results for 60 seconds.

Exit Points

ExitWhen
PassThe query ran successfully, even if it found zero matching records
ErrorThe query couldn't run: a connection problem, a data type mismatch, or an invalid data source

How It Works

When executed, the stage:

  1. Resolves your settings - Fills in the group name, filters, sorting, and query type from your flow's variables, and checks the group name for a data source marker or cache prefix
  2. Checks the cache - If caching is set up and results are still fresh, returns them without searching again
  3. Runs the search - Applies filters, sorting, and the record limit
  4. Builds the result - Returns a list for "All items as array", or calculates the statistics for the other query types, then stores it in cache if caching is set up
  5. Returns the output variables - Makes the results available to the rest of the flow

Key behavior: Zero matching records always goes to Pass, not Error. Filtering, sorting, and the record limit are all applied before the results are calculated, which keeps large queries efficient.

Common Use Cases

1. Get the Top 10 Scores

  • Query type: All items as array, Group name: GameScores, Order by: DESC, numOfRecords: 10

Result: {{topScores}} holds the 10 highest scores, highest first. Add Reverse order true to list them lowest to highest instead.

2. Calculate Sales Totals

  • Query type: Get sum and count etc, Group name: DailySales

Result: {{salesStats}}.sum, .count, .average, .minimum, and .maximum are all populated.

3. Filter by a Value Range, With Caching

  • Query type: All items as array, Group name: cache(30)::TestScores, filter1: 70, filter2: 90

Result: {{midRangeScores}} holds only the scores between 70 and 90, inclusive. Results are reused from cache for 30 seconds before the group is searched again.

Key Behaviors

FeatureBehavior
Zero results✓ Goes to Pass, not Error; returns an empty list, or zeroed-out statistics
Filter, sort, and limit orderFiltering and sorting happen first, then the record limit, then Reverse order
Caching✓ Use a cache(seconds):: prefix on the group name to avoid re-querying
Statistics on non-numeric data✗ Not supported; "Get sum and count etc" and "Get statistical averages" require numeric values
Reverse order on external data sources✗ Has no effect when querying an external data source, only your own stored data

Edge Cases

  • Zero results or a group that doesn't exist yet: The query still succeeds; an array query returns an empty list and statistics queries return a count of 0
  • Non-numeric values with a statistics query type: Fails with an error explaining the value must be a number
  • Limiting or filtering without ordering: Still works, but the result order isn't predictable and may differ between runs
  • Very large result sets: There's no built-in paging, so use Number of records to keep results manageable

Error Handling / Troubleshooting

IssueExitCommon CauseFix
"Are you trying to add a string to a number?" type errorErrorRunning a statistics query type against non-numeric valuesConfirm the stored values are numbers, or switch to "All items as array"
Results come back in an unpredictable orderPassNumber of records was set without also setting Order byAlways set Order by when limiting results
Cache doesn't seem to applyPassMissing parentheses around the cache durationUse the format cache(60)::GroupName, with parentheses around the number
No results foundPassGroup name typo, no data saved yet, or filters too narrowCheck the group name matches what was used when saving data, and loosen the filters
External data source query failsErrorThe referenced data source ID doesn't exist or isn't accessibleConfirm the data source ID and that it's accessible to your account
Expecting Order by to accept a column nameN/AConfiguration carried over from an older habitOrder by is a direction only (ASC/DESC/blank); it always sorts on the record's value
Reverse order doesn't seem to do anythingPassQuerying an external data source, or Number of records isn't setReverse order only applies to your own stored data, and only alongside Number of records

Best Practices

  • ✓ Cache frequently repeated queries with a cache(seconds):: prefix
  • ✓ Always set Order by when using Number of records, so results are predictable
  • ✓ Use filter1 and filter2 instead of fetching everything and filtering later in the flow
  • ✓ Pick the right query type: array for records, basic totals for simple aggregates, advanced statistics for deeper analysis
  • ✓ Use a Record name pattern to narrow the search when you don't need the whole group
  • ✓ Always connect the Error exit so query failures don't stop the flow silently

Related Stages

  • Save Data: Creates the data that Query Data searches
  • Fetch Data: Simpler retrieval when you already know the exact record
  • Delete Data: Remove records found by Query Data
  • Loop: Iterate through the list returned by an array query
  • Route Flow: Branch based on query results or statistics
  • Change Data: Process or transform the query results