> ## Documentation Index
> Fetch the complete documentation index at: https://docs.honeycomb.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Build a Query

> Construct queries against your telemetry data using Query Builder. Add filters, breakdowns, and calculations manually or start from a natural language prompt.

export const FlexStyleTable = ({columns, overflowWrap = "normal", children}) => {
  const colWidths = columns ? columns.trim().split(/\s+/) : [];
  const scopeKey = [columns || "auto", overflowWrap].join("-").replace(/[^a-zA-Z0-9-]/g, "-");
  const colRules = colWidths.map((width, i) => `[data-fst="${scopeKey}"] table th:nth-of-type(${i + 1}) { width: ${width}; }`).join("\n");
  const css = `
    [data-fst="${scopeKey}"] table {
      table-layout: ${colWidths.length > 0 ? "fixed" : "auto"};
      width: 100%;
    }
    ${colRules}
    [data-fst="${scopeKey}"] table td { overflow-wrap: ${overflowWrap}; }
  `.trim();
  return <div className="flex-style-table" data-fst={scopeKey}>
      <style>{css}</style>
      {children}
    </div>;
};

export const SchemaTable = ({children}) => {
  return <div className="schema-table">
      {children}
    </div>;
};

export const HnyIcon = ({alias, path, size = 16, iconColor}) => {
  const iconMap = {
    "home": "house.svg",
    "marker": "caretFilledDown.svg",
    "show-marker-options": "chatTextLeft.svg",
    "download": "arrowLineDown.svg",
    "trace-waterfall": "trace.svg",
    "show-query-details": "listDashes.svg",
    "table": "table.svg",
    "log-lines": "logLines.svg",
    "chart": "chartLine.svg",
    "show-settings": "gear.svg",
    "add": "plus.svg",
    "remove": "delete.svg",
    "persist": "caretDown.svg",
    "close": "close.svg",
    "copy": "copy.svg",
    "zoom-in": "magnifyingGlassPlus.svg",
    "zoom-out": "magnifyingGlassMinus.svg",
    "color-assignment": "drop.svg",
    "drag": "dots-six-vertical.svg",
    "drawer": "drawer.svg",
    "show-actions": "dotsThree.svg",
    "edit": "pencil.svg",
    "delete": "trash.svg",
    "move": "arrowsOutCardinal.svg",
    "show-legend": "circleInfo.svg",
    "usage-ok": "usageGood.svg",
    "usage-warning": "usageWarning.svg",
    "usage-danger": "usageDanger.svg",
    "open-query-builder": "query.svg",
    "home-menu": "house.svg",
    "query-menu": "query.svg",
    "boards-menu": "board.svg",
    "triggers-menu": "bell.svg",
    "slos-menu": "handshake.svg",
    "service-map-menu": "serviceMap.svg",
    "history-menu": "clockCounterClockwise.svg",
    "manage-data-menu": "cube.svg",
    "usage-menu": "usageGood.svg",
    "show-details": "dotsThreeVertical.svg",
    "resize-handle": "board-panel-resize-handle.png",
    "standard-dataset": "cube.svg",
    "trace-dataset": "cubeChat.svg",
    "all-datasets": "linkedSquares.svg",
    "share": "arrowBentRight.svg",
    "run-in-query-builder": "arrowSquareUpRight.svg",
    "link": "link.svg",
    "text": "text.svg",
    "receive": "arrowLineDown.svg",
    "process": "lightning.svg",
    "sample": "drop.svg",
    "send": "arrowLineUp.svg",
    "submit": "arrowUp.svg",
    "canvas-menu": "sparkle.svg",
    "canvas": "sparkle.svg",
    "private": "lockKey.svg",
    "shared": "people.svg",
    "expand": "caretDown.svg",
    "previous": "caretLeft.svg",
    "next": "caretRight.svg"
  };
  const iconBasePath = "/_assets/icons/";
  const iconPath = path || (alias ? `${iconBasePath}${iconMap[alias]}` : undefined);
  return <span className="hny-icon" style={{
    display: "inline-block",
    width: `${size}px`,
    height: `${size}px`,
    maskImage: `url(${iconPath})`,
    maskSize: "contain",
    maskRepeat: "no-repeat",
    maskPosition: "center",
    WebkitMaskImage: `url(${iconPath})`,
    WebkitMaskSize: "contain",
    WebkitMaskRepeat: "no-repeat",
    WebkitMaskPosition: "center",
    backgroundColor: iconColor || "var(--hny-icon-color)",
    verticalAlign: "middle"
  }} />;
};

**Query Builder** allows you to construct queries against your data to produce results for investigation and further exploration.
With Query Builder, enter field names, operators, and/or field values in clauses to construct or modify a query.

Use Query Builder to explore your data.

## Accessing Query Builder

In the left navigation menu, select **Query** (<HnyIcon alias="query-menu" />).
When the left navigation menu is compact, only the Query menu icon appears.

## Interacting with Query Builder

Below is an example of a blank Query Builder.

<Frame>
  <img src="https://mintcdn.com/honeycomb/FXLh0znw7mBYjjlc/_assets/images/query/new-query-blank-state.png?fit=max&auto=format&n=FXLh0znw7mBYjjlc&q=85&s=b12b7d334b9c7f122cc0bea0bbc91f2a" alt="An empty Query Builder form." width="2292" height="518" data-path="_assets/images/query/new-query-blank-state.png" />
</Frame>

### Clauses

A query in Honeycomb consists of up to six clauses:

* [**SELECT**](#visualize) - Performs a calculation and displays a corresponding graph over time. Most **SELECT** queries return a line graph while the `HEATMAP` visualization shows the distribution of data over time
* [**WHERE**](#where) - Filters based on field or attribute parameter(s)
* [**GROUP BY**](#group-by) - Groups fields by field or attribute parameter(s)
* [**ORDER BY**](#order-by) - Sort the results
* [**LIMIT**](#limit) - Specify a limit on how many results to return
* [**HAVING**](#having) - Filter results based on aggregate criteria

### Relational Fields

You can use relational fields in the **WHERE** and **GROUP BY** clauses to narrow your query to find traces that contain fields and values within a specific span type.
You can identify span types by their prefix.

<Note>
  Relational fields are available for use only within the Query Builder in the Honeycomb UI and only within the **WHERE** and **GROUP BY** clauses.

  Using relational fields automatically applies **AND** operators to the containing clause; all conditions within the clause must be met.
</Note>

#### Prefixes

Relational field span prefixes follow your trace structure and include:

* `root.` - Matches to the root span within a trace. Any additional filters in your query will search through fields only in the matched `root.` span.
* `parent.` - Matches to a direct parent span within a trace. Any additional filters in your query will search through fields only in the specified `parent.` span and its immediate child spans.
* `child.` - Matches to a single child span within a trace and returns the corresponding parent span. Any additional filters in your query will search through fields only in the matched `child.` span.
* `anyX.` (`any.`, `any2.`, `any3.`) - Matches to a single span anywhere in the trace. Use `anyX.` prefixes together to query for a trace that contains up to three spans, each with their own filters. Any additional filters applied to the same `anyX.` prefix will apply to the same matched span.
* `none.` - Matches to a single span and excludes any traces that contain that matched span. Any additional filters in your query will search through only fields not in the matched `none.` span.

  <Note>
    Using multiple of the same `anyX.` prefix will find many fields on a single span.
    Using an `anyX.` prefix in a **GROUP BY** clause requires specifying a field.
  </Note>

## Using Query Builder

To use Query Builder, enter terms.
For examples to try, refer to our [Query Examples](/investigate/query/examples-traces/).
As you type, Honeycomb autocomplete prompts with [relational field prefixes](#prefixes) and selectable query components.
Execute the query by selecting **Run Query** or pressing Shift + Enter on the keyboard.

<Note>
  Honeycomb supports keyboard shortcuts!
  Refer to a list of supported actions by typing `?` while on the Query Builder page.
</Note>

### Using Relational Fields

When you apply relational fields to your query, you can extend queries to use qualifying relationships that indicate where and how spans appear in a trace.

For example, if you managed an e-commerce platform and were trying to determine how many users received an error when they applied a discount code during checkout, you would be interested in finding any applicable spans in your trace.

This example query uses both the `root.` and `anyX.` prefixes to find the count of all spans where an error exists, where any span in the same trace is named `getDiscounts` and where its root span is named `/cart/checkout`.

| CLAUSE   | VALUE                                                                                       | DESCRIPTION                                                                                                                                                                                                                                                                            |
| -------- | ------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| SELECT   | COUNT                                                                                       | Calculates count.                                                                                                                                                                                                                                                                      |
| WHERE    | `error exists` AND <br /> `any.name = getDiscounts` AND <br /> `root.name = /cart/checkout` | Applies conditions to narrow your query: <ul><li>An error exists (primary condition)</li><li> The span is in the same trace and is named `getDiscounts` (secondary condition)</li><li>The span is contained within a root span named `/cart/checkout/` (secondary condition)</li></ul> |
| GROUP BY | `error`                                                                                     | Groups by the error.                                                                                                                                                                                                                                                                   |

After querying, you might see the following trace summary when you select a span from the query results:

<Frame>
  <img src="https://mintcdn.com/honeycomb/oJe-ncVHXR8RRGAw/_assets/images/query/relational-fields-example-trace.png?fit=max&auto=format&n=oJe-ncVHXR8RRGAw&q=85&s=e49d3bee2266f3fc7b21e227a9617b53" alt="A trace summary that displays multiple spans. Some spans have been highlighted, including a root span named /cart/checkout, its child named getDiscounts, and a span where an error exists." width="3116" height="1674" data-path="_assets/images/query/relational-fields-example-trace.png" />
</Frame>

To learn more about how to use relational fields with specific span types, visit [Query Reference: Relational Fields](#relational-fields-1).

## Query Builder Results

The default output for most queries will include:

1. a visualization, or a graph over time
2. a [summary table](#select-summary-table)

The precise composition depends on what your query contains.

* Specifying a **SELECT** clause causes a visualization to be drawn, representing that calculated value over time
* Multiple **SELECT** clauses result in multiple graphs, one for each calculation.
* Specifying a **GROUP BY** clause results in the graph having multiple lines, one for each group.
  The summary table will contain a single row for each unique group.
* Leaving **SELECT** blank results in raw event data being returned without any summarization.

## Editing Queries in Query Builder

Click on any box in the Query Builder to edit the clauses there.
Selecting the **X** removes the field from the clause.
In the image below, the user already entered **SELECT** `COUNT` and **GROUP BY** `hostname`.
When editing, they add a new **WHERE** clause on `app.status_code`.
Honeycomb autocomplete helps construct the query.

<Frame>
  <img src="https://mintcdn.com/honeycomb/oJe-ncVHXR8RRGAw/_assets/images/query/query-builder-open.png?fit=max&auto=format&n=oJe-ncVHXR8RRGAw&q=85&s=d5059e2916242b062618eedfe8da382f" alt="Screenshot that illustrates editing the Query Builder" width="1978" height="1124" data-path="_assets/images/query/query-builder-open.png" />
</Frame>

### Change Datasets

In the upper left corner above the Query Builder, use the **Dataset Switcher** to choose to query a specific Dataset or all Datasets within your Environment.
The latter option may be useful if you need to reference events that span across multiple services.

When you switch datasets, Honeycomb will load the existing query on that dataset, but it will not run it automatically.

You can also set a default scope for new queries per environment in [Environment Settings](/reference/honeycomb-ui/environment/environment-settings/).

### Change and Compare Query Time Ranges

In the bottom right corner below the Query Builder, use the **time picker** to modify the selected time span of the data in your query.
Use a preset time range or a custom time range.

Honeycomb supports running queries across different periods of time, so you can compare results to see how your systems change.

Run a Time Comparison query by selecting a time range under **Compare to previous time period** in the time picker.
Honeycomb then will run a query as defined in the Query Builder and another query for the time comparison range selected.

## Query Assistant

Query Assistant is an experimental feature that generates Honeycomb queries based on your natural language query (NLQ) input.

Use Query Assistant to:

* learn how to query in Honeycomb faster
* start with a query and then further refine to explore your data
* onboard new team members to Honeycomb
* explore an unfamiliar dataset

### Using Query Assistant

You can access Query Assistant underneath the Query Builder.
To use Query Assistant, enter your prompt in the search box and select **Get Query**, or select one of the suggested questions below the search box.
Based on your entry or selection, Query Assistant creates and runs a query in the Query Builder.
Results appear after the screen refreshes.

<Frame>
  <img src="https://mintcdn.com/honeycomb/oJe-ncVHXR8RRGAw/_assets/images/query/query-assistant.png?fit=max&auto=format&n=oJe-ncVHXR8RRGAw&q=85&s=4fb5c4f4b7b513c6f8956869880e36b8" alt="Screenshot of Query Assistant with search box and three suggested queries" width="813" height="176" data-path="_assets/images/query/query-assistant.png" />
</Frame>

### Viewing Query Assistant

You can expand and collapse the Query Assistant display.
Any changes you make will persist.
You can also control your team's ability to use Query Assistant in [Team Settings](/reference/honeycomb-ui/account/team-settings/).
To learn how to enable or disable Query Assistant, visit [Teams: Manage Behavior](/configure/teams/manage-behavior/#manage-query-assistant).

### Best Practices

Query Assistant uses machine learning systems, such as a Large Language Model (LLM) with a generative pre-trained transformer, to assist in creating Honeycomb Queries using natural language.

In addition to your schema, Query Assistant uses the following as context:

* The current query, if it exists
* Suggested Queries for your dataset
* [Dataset Definitions](/configure/datasets/definitions/)

When modifying the current query, Query Assistant translates your prompts into additional query clauses.
For example, when given a query that displays overall latency and the prompt "only show errors", Query Assistant usually adds a **WHERE** clause to return spans with an error field present and set to `true`.

When a dataset has Suggested Queries configured, Query Assistant analyzes its fields and generates better results.
We recommend configuring your own Suggested Queries for datasets that do not conform to common standards defined by OpenTelemetry instrumentation.

Query Assistant uses the fields defined in [Dataset Definitions](/configure/datasets/definitions/).
For example, OpenTelemetry (and Honeycomb, by default) recognizes any error as a boolean value in the `error` field.
When a Dataset Definition overrides this default with a string value in the `app.error` field, Query Assistant uses the `app.error` field instead of the `error` field when it evaluates prompts.

### Limitations

A user can use up to 50 natural language queries per 24 hours.

Query Assistant is not available to any Honeycomb customer who has signed a HIPAA Business Associate Agreement (BAA).

### Data Use

Honeycomb uses OpenAI's API for Query Assistant.
Honeycomb sends information to OpenAI's API for the purpose of generating a runnable query based on your input.
Data is only sent when you execute a natural language query.
In addition, Honeycomb does not use any data to train ML models.
In the future, we are interested in using data to create more personalized user experiences, but we have no plans to incorporate data itself, and all data is still subject to our Data Retention window.

What Honeycomb sends to OpenAI:

* Your natural language input
* The names of fields in your dataset schema

What Honeycomb does **NOT** send to OpenAI:

* Identifying information
* The values of data sent to Honeycomb

OpenAI does not train models on data sent via their API.
OpenAI does retain all data for a short period of time to monitor for abuse and misuse.
Honeycomb does not use their opt-in mechanism for training and has no plans to offer that as an option for users at this time.

OpenAI's API exposes the base Large Language Model (LLM) that ChatGPT also uses.
ChatGPT adds additional layers of machine learning systems suited for a general-purpose chat application and uses a subset of data it receives to further train their systems.
The systems that ChatGPT adds on top of the LLM are not part of Honeycomb's product implementation.

## Query Reference

### SELECT

Honeycomb supports a wide range of calculations to provide insight into your events.
When a grouping is provided, calculations occur within each group; otherwise, anything calculated is done so over all matching events.

For example, say you have collected the following events from your web server logs:

<SchemaTable>
  | Timestamp        | uri    | status\_code | response\_time\_ms |
  | :--------------- | :----- | :----------- | :----------------- |
  | 2016-08-01 07:30 | /about | 500          | 126                |
  | 2016-08-01 07:45 | /about | 200          | 57                 |
  | 2016-08-01 07:57 | /docs  | 200          | 82                 |
  | 2016-08-01 08:03 | /docs  | 200          | 23                 |
</SchemaTable>

Specifying a visualization for a particular attribute (`P95(response_time_ms)`for example) means to apply the aggregation function (in this case, `P95`, or taking the 95th [percentile](https://en.wikipedia.org/wiki/Percentile)) over the values for the attribute (`response_time_ms`) across all input events.

Defining multiple **SELECT** clauses is common and can be useful, especially when comparing their outputs to each other.
For example, it can be useful to see both the `COUNT` and the `P95(duration)` for a set of events to understand whether latency changes follow volume changes.

While most **SELECT** queries return a line graph, the [`HEATMAP`](/investigate/analyze/visualize-events/) visualization allows you see the distribution of data in a rich and interactive way.
Heatmaps also allow you to find outliers in data using [BubbleUp](/investigate/analyze/identify-outliers/).

#### SELECT: Basic Case

Scenario: we want to capture overall statistics for our web server.
Given our four-event dataset [described above](#select), consider a query which contains:

* Visualize the overall `COUNT`
* Visualize the `AVG` of `response_time_ms` values
* Visualize the `P95` of `response_time_ms` values

These calculations would return statistics across the entirety of our dataset:

<SchemaTable>
  | COUNT | AVG(response\_time\_ms) | P95(response\_time\_ms) |
  | :---- | :---------------------- | :---------------------- |
  | 4     | 72                      | 119.4                   |
</SchemaTable>

#### SELECT: COUNT\_DATAPOINTS

`COUNT_DATAPOINTS` returns the total count of datapoints ingested across all metric fields in a metrics dataset. Use it to understand data volume and track what is driving your usage. The `COUNT_DATAPOINTS` aggregate can only be used with time-series metrics data.

A **datapoint** is a single recorded value for a metric at a point in time, for a unique combination of attributes. Datapoints are the unit by which metrics usage is billed. Every active time series is a unique combination of metric name and attributes, such as `http.server.request.duration` where `k8s.node.name=node-1` which continuously produces datapoints over time. High attribute cardinality means more time series, and therefore more datapoints.

Use `COUNT_DATAPOINTS` to track billing usage over a time range or to spot metric ingestion spikes.

<Note>
  `COUNT_DATAPOINTS` data is only available from February 13, 2026 onward. Queries that include time ranges before this date will only reflect data ingested after that date.
</Note>

#### SELECT: COUNT\_DATAPOINTS(metric\_field\_name)

`COUNT_DATAPOINTS(<metric_field_name>)` returns the count of datapoints for a specific metric field. Only rows where that column has a value are counted. The `COUNT_DATAPOINTS(<metric_field_name>)` aggregate can only be used with time-series metrics data.

Use this when you want to isolate the datapoint volume of a single metric. For example, comparing ingestion across metrics or identifying which metric is driving a cost increase.

<Note>
  If any metric data has been deleted, `COUNT_DATAPOINTS` will still include those deleted datapoints in its count. `COUNT_DATAPOINTS(metric_field_name)` excludes deleted data.
</Note>

### SELECT: HISTOGRAM\_COUNT(metric\_field\_name)

`HISTOGRAM_COUNT(<metric_field_name>)` returns the count of observations in a histogram metric field, across the rows and time included in the query.
This aggregate can only be used on Metrics 2.0 histogram fields.

#### SELECT Summary Table

The **SELECT** clause returns both a time series graph and a column of values in the result summary table.
Note that in the graph, the values shown are aggregated for each interval at the current granularity.
Conversely, the values shown in the summary table are calculated across the entire time range for that query.

These results can be a little surprising for some calculations.
The `P95(duration_ms)` across the entire time range may not look quite like the `P95` value at any given point of the curve, because there may be spikes and bumps in the underlying data that are hidden in the time intervals.

The summary table for a `HEATMAP` shows a histogram of values of that field across the full time range.

#### SELECT Operations

Most **SELECT** operations take a single argument, with the exception of `COUNT` and `COUNT_DATAPOINTS`, that optionally take an argument, and `CONCURRENCY`, which takes no arguments.
Events that do not have a relevant attribute are ignored, and will not be counted in aggregations.

In the chart below, `<field_name>` refers to any field name while the `<numeric_field_name>` argument refers to a float or integer field.

<FlexStyleTable columns="33% 67%">
  | Aggregate                                        | Meaning                                                                                                                                                                                                  |
  | ------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
  | `COUNT`                                          | The number of events                                                                                                                                                                                     |
  | `COUNT(<field_name>)`                            | The number of events with a non-null value for a field                                                                                                                                                   |
  | `COUNT_DISTINCT(<field_name>)`                   | The count of different distinct values in a field. `COUNT_DISTINCT` is estimated using the HyperLogLog algorithm.                                                                                        |
  | `COUNT_DATAPOINTS`                               | The total count of datapoints ingested across all metric fields in a metrics dataset.                                                                                                                    |
  | `COUNT_DATAPOINTS(<metric_field_name>)`          | The count of datapoints for a specified metric field in a metrics dataset. Only rows where the specified field has a value are counted.                                                                  |
  | `HISTOGRAM_COUNT(<metric_histogram_field_name>)` | The count of observations recorded in a specified histogram field. Requires a histogram field in a Metrics 2.0 dataset as the parameter.                                                                 |
  | `SUM(<numeric_field_name>)`                      | The sum of the field value                                                                                                                                                                               |
  | `AVG(<numeric_field_name>)`                      | The average value of the field                                                                                                                                                                           |
  | `MAX(<numeric_field_name>)`                      | The maximum value of the field                                                                                                                                                                           |
  | `MIN(<numeric_field_name>)`                      | The minimum value of the field                                                                                                                                                                           |
  | `P001(<numeric_field_name>)`                     | The .1-th percentile of the field. `P001` is estimated using the t-digest algorithm.                                                                                                                     |
  | `P01(<numeric_field_name>)`                      | The 1st percentile of the field. `P01` is estimated using the t-digest algorithm.                                                                                                                        |
  | `P05(<numeric_field_name>)`                      | The 5th percentile of the field. `P05` is estimated using the t-digest algorithm.                                                                                                                        |
  | `P10(<numeric_field_name>)`                      | The 10th percentile of the field. `P10` is estimated using the t-digest algorithm.                                                                                                                       |
  | `P20(<numeric_field_name>)`                      | The 20th percentile of the field. `P20` is estimated using the t-digest algorithm.                                                                                                                       |
  | `P25(<numeric_field_name>)`                      | The 25th percentile of the field. `P25` is estimated using the t-digest algorithm.                                                                                                                       |
  | `P50(<numeric_field_name>)`                      | The 50th percentile of the field. `P50` is estimated using the t-digest algorithm.                                                                                                                       |
  | `P75(<numeric_field_name>)`                      | The 75th percentile of the field. `P75` is estimated using the t-digest algorithm.                                                                                                                       |
  | `P80(<numeric_field_name>)`                      | The 80th percentile of the field. `P80` is estimated using the t-digest algorithm.                                                                                                                       |
  | `P90(<numeric_field_name>)`                      | The 90th percentile of the field. `P90` is estimated using the t-digest algorithm.                                                                                                                       |
  | `P95(<numeric_field_name>)`                      | The 95th percentile of the field. `P95` is estimated using the t-digest algorithm.                                                                                                                       |
  | `P99(<numeric_field_name>)`                      | The 99th percentile of the field. `P99` is estimated using the t-digest algorithm.                                                                                                                       |
  | `P999(<numeric_field_name>)`                     | The 99.9th percentile of the field. `P999` is estimated using the t-digest algorithm.                                                                                                                    |
  | `HEATMAP(<numeric_field_name>)`                  | A heatmap of the distribution of that field                                                                                                                                                              |
  | `CONCURRENCY`                                    | The concurrency of the current query, for tracing-enabled datasets only. This is a complex operation; please see the [detailed explanatory page](/investigate/query/build/visualize-concurrency/) on it. |
  | `RATE_AVG(<numeric_field_name>)`                 | The difference between subsequent field values after applying the `RATE_AVG` operator. [Learn more about the RATE operators](/investigate/query/build/visualize-rate/).                                  |
  | `RATE_SUM(<numeric_field_name>)`                 | The difference between subsequent field values after applying the `RATE_SUM` operator. [Learn more about the RATE operators](/investigate/query/build/visualize-rate/).                                  |
  | `RATE_MAX(<numeric_field_name>)`                 | The difference between subsequent field values after applying the `RATE_MAX` operator. [Learn more about the RATE operators](/investigate/query/build/visualize-rate/).                                  |
</FlexStyleTable>

### WHERE

The **WHERE** clause allows you to constrain events by some attribute besides time. For example, you may want to ignore an outlier case or isolate events triggered by a particular actor or circumstance.

For example, say you have collected the following events from your web server logs:

<SchemaTable>
  | Timestamp        | uri    | status\_code |
  | :--------------- | :----- | :----------- |
  | 2016-08-01 08:15 | /about | 500          |
  | 2016-08-01 08:22 | /about | 200          |
  | 2016-08-01 08:27 | /docs  | 403          |
</SchemaTable>

You can define any number of arbitrary constraints based on event values.
**WHERE** clauses work in concert with the specified time range to define the events that are ultimately considered by any **GROUP BY** or **SELECT** clauses.

<Note>
  The **WHERE** clause does not require string delimiters or escape characters. For example, to match a URI of `/docs`, you can enter `uri = /docs`.
</Note>

#### WHERE: Basic Case

Scenario: we want to understand the frequency of unsuccessful web requests.
Given our three-event dataset [described above](#where), consider a query which contains:

* **SELECT** the overall `COUNT`
* **WHERE** `status_code != 200`

The **WHERE** clause removes the successful event (our `/about` web request returning a `200`) from consideration, and only counts the first and third events towards our **SELECT** clause:

<SchemaTable>
  | COUNT |
  | :---- |
  | 2     |
</SchemaTable>

#### WHERE: Multiple Clauses

Scenario: we want to refine our constraints further, to span multiple attributes for each event.
Combining **WHERE** clauses returns events that satisfy either the **intersection** of all specified **WHERE** clauses, or the **union**.
Given our three-event dataset [described above](#where), consider a query which contains:

* Where `uri = "/about"`
* AND `status_code != 200`

As all three events are considered by the **WHERE** clauses, only the first one satisfies both:

<SchemaTable>
  | Timestamp        | uri    | status\_code |
  | :--------------- | :----- | :----------- |
  | 2016-08-01 08:55 | /about | 500          |
</SchemaTable>

Honeycomb also allows you to look at the **union** of clauses by setting to an `OR`.

* **WHERE** `status_code = 500`
* OR `status_code = 403`

<SchemaTable>
  | Timestamp        | uri    | status\_code |
  | :--------------- | :----- | :----------- |
  | 2016-08-01 08:55 | /about | 500          |
  | 2016-08-01 08:27 | /docs  | 403          |
</SchemaTable>

#### WHERE: Relational Fields

You can use relational fields in your **WHERE** clause to narrow your query to find traces that contain fields and values within a specific span type.
To learn more and explore some examples, visit [Relational Fields](#relational-fields-1) in this reference.

#### WHERE Operations

`WHERE` operations may take one or more attributes.
Events are only counted if they have a relevant attribute, except in the case of the `does-not-exist` operation.

| Operation     | Opposite              | Arguments | Meaning                                                                         |
| :------------ | :-------------------- | :-------- | :------------------------------------------------------------------------------ |
| `=`           | `!=`                  | 1         | Exact numerical or string match                                                 |
| `starts-with` | `does-not-start-with` | 1         | String start match                                                              |
| `ends-with`   | `does-not-end-with`   | 1         | String end match                                                                |
| `exists`      | `does-not-exist`      | 0         | Checks for non-null values                                                      |
| `>`, `>=`     | `<`, `<=`             | 1         | numerical comparison                                                            |
| `contains`    | `does-not-contain`    | 1         | string inclusion: checks whether the attribute matches a substring of the value |
| `in`          | `not-in`              | 1+        | list inclusion: checks whether the attribute matches any item in the list       |

The syntax for the `in` operator does not use parentheses.
For example, `request_method in GET,POST`

### GROUP BY

Being able to separate a series of events into groups by attribute is a powerful way to compare segments of your dataset against each other.

For example, say you have collected the following events from your web server logs:

<SchemaTable>
  | Timestamp        | uri    | status\_code |
  | :--------------- | :----- | :----------- |
  | 2016-08-01 07:30 | /about | 500          |
  | 2016-08-01 07:45 | /about | 200          |
  | 2016-08-01 07:57 | /docs  | 200          |
</SchemaTable>

You might want to analyze your web traffic in groups based on the `uri` ("/about" vs "/docs") or the `status_code` (`500` versus `200`).
Choosing to group by `uri` would return two result rows: one representing events in which `uri="/about"` and another representing events in which `uri="/docs"`.
Each of these grouped results rows will be represented by a single line on a graph.

When using GROUP BY for more than one attribute, Honeycomb will consider each unique combination of values as a single group.
Here, choosing to group by both `uri` and `status_code` will return three groups: `/about`+`500`, `/about`+`200`, and `/docs`+`200`.

Grouping, paired with calculation, can often reveal interesting patterns in your underlying events—grouping by `uri`, for example, and calculating response time stats will show you the slowest (or fastest) `uri`s.

<Tip>
  Honeycomb supports grouping your data based on any attribute in an event, though you will likely receive the clearest results by choosing an attribute with an uneven distribution within your data.
</Tip>

The **GROUP BY** dropdown list also has a shortcut to [create a calculated field](/configure/environments/calculated-fields/).

#### Grouping and Selecting: Better Together

Scenario: we want to examine performance of our web server by endpoint.
Given our four-event dataset [described above](#select), consider a query which contains:

* Group by `uri`
* Select the overall `COUNT`
* Select the `AVG` of `response_time_ms` values

Pairing a Grouping clause with a Select clause results in events being grouped by `uri`; Honeycomb draws one line for each group, and calculates statistics within each group:

<SchemaTable>
  | uri    | COUNT | AVG(response\_time\_ms) |
  | :----- | :---- | :---------------------- |
  | /about | 2     | 91.5                    |
  | /docs  | 2     | 52.5                    |
</SchemaTable>

This technique is particularly powerful when paired with an Order By and a Limit to return "Top K"-style results.

In this figure, the user has a **SELECT** `COUNT`, and **GROUP BY** `eventtype`.
The two curves, in purple and orange, show the two groups.
The popup shows that the user is hovering the `trace_span` eventtype, which has a count of 405 in that 15-second time range.

<Frame>
  <img src="https://mintcdn.com/honeycomb/oJe-ncVHXR8RRGAw/_assets/images/query/query_results_table.png?fit=max&auto=format&n=oJe-ncVHXR8RRGAw&q=85&s=f76f2fba002b5ff29532f8ca1cc25e99" alt="Query Builder with two result rows" width="3600" height="2574" data-path="_assets/images/query/query_results_table.png" />
</Frame>

When you move your cursor over the results table at the bottom of the page, each row is highlighted in turn.
In the image below, the user has highlighted `request` and sees the orange line highlighted, and the purple line dimmed.

<Frame>
  <img src="https://mintcdn.com/honeycomb/oJe-ncVHXR8RRGAw/_assets/images/query/query_highlight_results.png?fit=max&auto=format&n=oJe-ncVHXR8RRGAw&q=85&s=479cbbac5040d47812da8411b0d75f0a" alt="Query Builder highlighting the request row" width="3600" height="2589" data-path="_assets/images/query/query_highlight_results.png" />
</Frame>

Rollover for heatmaps is slightly different, as described on the [Heatmaps](/investigate/analyze/visualize-events/) page.

<Note>
  **50-Series Visualization Limit**: Honeycomb visualizes only the top 50 groups by the selected aggregation (e.g., MAX, MIN, AVG) in graphs, regardless of the **LIMIT** clause value. The **LIMIT** clause controls how many rows appear in the results table, but we will only ever show up to the top 50 groups as series in the visualization. When you change the time range, the visualized groups will change based on the query's sort clause and the total value of each aggregation within the query's time range, which can cause series to appear or disappear when zooming in or out.
</Note>

<Note>
  **Time Bucket Edge Effects**: The first and last data points in a graph may represent shorter time intervals when query boundaries don't align with the selected granularity. For example, with 2-minute granularity and a query ending at 08:32:44, the bucket for 08:32:00 will only contain 44 seconds of data, which can make it look like data is missing or dropping unexpectedly at the edges of graphs.
</Note>

#### GROUP BY: Relational Fields

You can use relational fields in your **GROUP BY** clause to separate a series of events into groups.
To learn more and explore some examples, visit [Relational Fields](#relational-fields-1) in this reference.

### ORDER BY

**ORDER BY** clauses define how rows will be sorted in the results table.

For example, say you have collected the following events from your web server logs:

<SchemaTable>
  | Timestamp        | uri    | status\_code | response\_time\_ms |
  | :--------------- | :----- | :----------- | :----------------- |
  | 2016-08-01 09:17 | /about | 200          | 57                 |
  | 2016-08-01 09:18 | /about | 500          | 234                |
  | 2016-08-01 09:20 | /404   | 200          | 12                 |
  | 2016-08-01 09:25 | /docs  | 200          | 82                 |
</SchemaTable>

You can define any number of **ORDER BY** clauses in a query and they will be respected in the order they are specified.

The **ORDER BY** clauses available to you for a particular query are influenced by whether any **GROUP BY** or **SELECT** clauses are also specified.
If none are, you may order by any of the attributes contained in the dataset.
However, once a **GROUP BY** or **SELECT** clause exists, you may only order by the values generated by those clauses.

#### ORDER BY: Basic Case

Scenario: we just want to get a sense of the slowest endpoints in our web server.
Given our four-event dataset [described above](#order-by), consider a query which contains:

* Order by `response_time_ms` in descending (`DESC`) order
* Limit to 1 result

Remember that when no Select clauses are defined, we simply return raw events as the result rows:

<SchemaTable>
  | Timestamp        | uri    | status\_code | response\_time\_ms |
  | :--------------- | :----- | :----------- | :----------------- |
  | 2016-08-01 09:18 | /about | 500          | 234                |
</SchemaTable>

#### ORDER BY as Paired with SELECT and GROUP BY Clauses

Scenario: we want to capture statistics for our web server and know what we are looking for (long `response_time_ms`s).
Given our four-event dataset [described above](#order-by), consider a query which contains:

* **SELECT** `P95(response_time_ms)`, or the p95 of `response_time_ms` values
* **GROUP BY** `uri`
* **ORDER BY** `P95(response_time_ms)` in descending (`DESC`) order
* **LIMIT** to the first `2` results

Our **GROUP BY** and **SELECT** queries influence **what** will be returned as result rows (`uri` and the `P95(response_time_ms)` for events within each distinct `uri` group), while the **ORDER BY** determines the sort order of those results (longest `P95(response_time_ms)` first) and the **LIMIT** throws away any results beyond the top `2`:

<SchemaTable>
  | uri    | P95(response\_time\_ms) |
  | :----- | :---------------------- |
  | /about | 225.15                  |
  | /docs  | 82                      |
</SchemaTable>

As you can see, any results referencing the event with `uri="/404"` was excluded from our result set as a result of its relatively low `response_time_ms`.

This sort of Top K query is particularly valuable when working with high-cardinality data sets, where a **GROUP BY** clause might split your dataset into a very large number of groups.

### LIMIT

The **LIMIT** clause provides a maximum number of result rows to return.
By default, queries return 100 result rows.
The **LIMIT** clause allows you to specify up to 1000 rows.

### HAVING

The **HAVING** clause allows you to filter on the results table.
This operation is distinct from the **WHERE** clause, which filters the underlying events.
A **HAVING** filter can help further refine your query results when grouping on a high-cardinality attribute, which can result in many different rows in the result table.
It can also work in tandem with an **ORDER BY** clause.
**ORDER BY** allows you to order the results, and **HAVING** filters them.

Like **ORDER BY**, **HAVING** selects its series from the results table.

For example, consider a query on **SELECT** `COUNT, P95(duration_ms)` and **GROUP BY** `endpoint`.
This query would show how many times each endpoint ran, and how often it did so.
The results table from this query might look something like this:

<SchemaTable>
  | endpoint          | COUNT | P95(duration\_ms) |
  | :---------------- | :---- | :---------------- |
  | /add-to-cart      | 521   | 45                |
  | /remove-from-cart | 1021  | 54                |
  | /unused-endpoint  | 2     | 1500              |
  | /empty-page       | 10    | 1700              |
</SchemaTable>

You might want to ignore the rarest entries when they are least likely to be useful.
One way to do that is to add a **HAVING** clause:

The clause **HAVING** `COUNT > 100` will filter to only results with more than 100 hits on them.
You can then **ORDER BY** `P95( duration_ms )` to sort the results to find the slowest endpoints.

**HAVING** works by filtering specifically on aggregations across all results in the selected time range.
It currently does not filter time periods that match the criteria.
Take a look at the following example.
Each event has counts ranging from 0 - 9 across the time range.

<Frame>
  <img src="https://mintcdn.com/honeycomb/oJe-ncVHXR8RRGAw/_assets/images/query/query_result_having.png?fit=max&auto=format&n=oJe-ncVHXR8RRGAw&q=85&s=085d55d6cb2b40d81e5d7f4a0e4189d8" alt="Query Builder highlighting the request row" width="844" height="514" data-path="_assets/images/query/query_result_having.png" />
</Frame>

You may want to filter specifically on counts greater than 5 in the example and add the clause **HAVING** `COUNT > 5`.
This will still return all results in the image, since **HAVING** filters based off the total in the result table where all values are shown to have counts > 5.

#### HAVING Clause Options

The **HAVING** clause always refers to one of the **SELECT** clauses.
It then takes one or more numeric arguments.

| Operator | Opposite | Arguments | Meaning             |
| -------- | -------- | --------- | ------------------- |
| =        | !=       | 1         | numerical equality  |
| >, >=    | \<, \<=  | 1         | comparison          |
| in       | not-in   | 1+        | existence in a list |

The `in` operator compares where a value is one of a set: `COUNT in 10, 20, 30` checks whether the COUNT is precisely one of those values.
The syntax for the `in` operator does not use parentheses.

### Relational Fields

You can use relational fields to narrow your query to find traces that contain fields and values within a specific span type.
Span types are identified by prefixes that follow your trace structure.

You can use relational fields in **WHERE** or **GROUP BY** clauses in the Honeycomb UI.

<Note>
  If you use relational fields, your conditions will be joined using **AND** operators by default.
</Note>

<Tip>
  To make your queries run faster, add filters to narrow possible matches.
  Filtering on joined events is particularly helpful.

  For example, if you include a filter like `any.name = foo`, also include a filter like `any.service_name = bar`.
  Adding the additional filter keeps us from searching your entire environment, which lets us speed things up!
</Tip>

To learn about more best practices, visit [Best Practices for Querying using Relational Fields](/get-started/best-practices/relational-fields/).

#### Prefix: root

The `root.` prefix matches to the root span within a trace.
When you use it, additional filters in your query will match only for spans in traces that match the conditions on the root span.
You can also query with `root.` on its own.

If you are looking for spans somewhere in a trace that you know starts with certain fields, use `root.`.

So you might use a query that contains:

* **SELECT** `COUNT`
* **WHERE** `name = HGET` AND `root.name = /cart` AND `root.duration_ms > 1000`

<Frame>
  <img src="https://mintcdn.com/honeycomb/oJe-ncVHXR8RRGAw/_assets/images/query/relational-fields-example-root-query.png?fit=max&auto=format&n=oJe-ncVHXR8RRGAw&q=85&s=ec4178f8c2cce3a458d5e450883aae31" alt="Honeycomb Query Builder with the discussed query options entered." width="1148" height="709" data-path="_assets/images/query/relational-fields-example-root-query.png" />
</Frame>

And you might see the following trace summary when you select a span from the query results:

<Frame>
  <img src="https://mintcdn.com/honeycomb/oJe-ncVHXR8RRGAw/_assets/images/query/relational-fields-example-root-trace.png?fit=max&auto=format&n=oJe-ncVHXR8RRGAw&q=85&s=60ab735e7304c4e8be32f6eaca914a9c" alt="A trace summary that displays multiple spans. Some spans have been highlighted, including the root span named /cart and one of its nested child spans named HGET. The root duration, which is greater than 1000 ms, has also been highlighted." width="1998" height="1634" data-path="_assets/images/query/relational-fields-example-root-trace.png" />
</Frame>

To explore more examples related to using relational fields with the `root.` prefix, visit [Examples: Query for Traces](/investigate/query/examples-traces/#root-prefix).

#### Prefix: parent

The `parent.` prefix matches to a direct parent span within a trace.
When you use it, additional filters in your query will search through fields only in the specified `parent.` span's immediate child spans.
For example, if you know a service is being called at a lower level inside a trace, and you want to find one of its direct child spans, use `parent.`.

You can also use `parent.` with no additional filters to count the child spans of a parent span.
When you do so, Honeycomb will match to one parent span per trace.

So you might use a query that contains:

* **SELECT** `COUNT`
* **WHERE** `status_message exists` AND `parent.service.name = frontend`
* **GROUP BY** `status_message` `service.name` `name`

<Frame>
  <img src="https://mintcdn.com/honeycomb/oJe-ncVHXR8RRGAw/_assets/images/query/relational-fields-example-parent-query.png?fit=max&auto=format&n=oJe-ncVHXR8RRGAw&q=85&s=9547b0c9bc62c2481cceb3a1c945304e" alt="Honeycomb Query Builder with the discussed query options entered." width="800" height="546" data-path="_assets/images/query/relational-fields-example-parent-query.png" />
</Frame>

And you might see the following trace summary when you select a span from the query results:

<Frame>
  <img src="https://mintcdn.com/honeycomb/oJe-ncVHXR8RRGAw/_assets/images/query/relational-fields-example-parent-trace.png?fit=max&auto=format&n=oJe-ncVHXR8RRGAw&q=85&s=98ce806e1d2b3cdafd1ecf7da18d1d64" alt="A trace summary that displays multiple spans. Some spans have been highlighted, including a parent span named product/id with a service.name of frontend." width="800" height="509" data-path="_assets/images/query/relational-fields-example-parent-trace.png" />
</Frame>

To explore more examples related to using relational fields with the `parent.` prefix, visit [Examples: Query for Traces](/investigate/query/examples-traces/#parent-prefix).

#### Prefix: child

The `child.` prefix matches to a direct child span within a trace.
When you use it, additional filters in your query will search through fields only in the specified `child.` span.

For example, if you know a service is being called on a specific lower-level span inside a trace, and you want to search only that span, use `child.`.

<Tip>
  * If you use multiple `child.` relational fields in the same clause, Honeycomb will apply them all to the same span.
  * `child.` returns results in random order.
</Tip>

So you might use a query that contains:

* **SELECT** `COUNT`
* **WHERE** `name = /cart`
* **GROUP BY** `child.name`

<Frame>
  <img src="https://mintcdn.com/honeycomb/oJe-ncVHXR8RRGAw/_assets/images/query/relational-fields-example-child-query.png?fit=max&auto=format&n=oJe-ncVHXR8RRGAw&q=85&s=51c5c6bb55248c9e858d3432d0145beb" alt="Honeycomb Query Builder with the discussed query options entered." width="800" height="564" data-path="_assets/images/query/relational-fields-example-child-query.png" />
</Frame>

And you might see the following trace summary when you select a span from the query results:

<Frame>
  <img src="https://mintcdn.com/honeycomb/oJe-ncVHXR8RRGAw/_assets/images/query/relational-fields-example-child-trace.png?fit=max&auto=format&n=oJe-ncVHXR8RRGAw&q=85&s=bbfdb9db3549893b1b5cc69513284af9" alt="A trace summary that displays multiple spans. A span named cart has been highlighted, along with the child span with the name of msdemo.CartService/GetCart" width="800" height="523" data-path="_assets/images/query/relational-fields-example-child-trace.png" />
</Frame>

To explore more examples related to using relational fields with the `child.` prefix, visit [Examples: Query for Traces](/investigate/query/examples-traces/#child-prefix).

#### Prefix: anyX

The `anyX.` prefixes (`any.`, `any2.`, `any3.`) match to a single span anywhere within a trace.
Use `anyX.` prefixes together to query for a trace that contains up to three spans, each with their own filters.
When you use an `anyX.` prefix, additional filters in your query will apply only to the same matched span.

<Info>
  If you are using an `anyX.` prefix in your GROUP BY clause, you must also use the same `anyX.` prefix in your **WHERE** clause.
  Doing so will ensure your joins are accurate.
</Info>

<Tip>
  * If you use multiple `anyX.` relational fields in the same clause, Honeycomb will apply them all to the same span.
  * `anyX.` returns results in random order.
</Tip>

So you might use a query that contains:

* **SELECT** `COUNT`
* **WHERE** `name = getDiscounts` AND `any.http.host = cartservice:7070` AND `any.duration_ms > 100`

<Frame>
  <img src="https://mintcdn.com/honeycomb/oJe-ncVHXR8RRGAw/_assets/images/query/relational-fields-example-any-query.png?fit=max&auto=format&n=oJe-ncVHXR8RRGAw&q=85&s=6bfe91966fdfcae97850e4f54514150b" alt="Honeycomb Query Builder with the discussed query options entered." width="2300" height="676" data-path="_assets/images/query/relational-fields-example-any-query.png" />
</Frame>

And you might see the following trace summary when you select a span from the query results:

<Frame>
  <img src="https://mintcdn.com/honeycomb/oJe-ncVHXR8RRGAw/_assets/images/query/relational-fields-example-any-trace.png?fit=max&auto=format&n=oJe-ncVHXR8RRGAw&q=85&s=73ac21d3a864a5ddbe9eb3fdf6f520a6" alt="A trace summary that displays multiple spans. A span named getDiscounts has been highlighted, along with the duration_ms and http.host for a span that has http.host of cartservice:7070 and duration_ms greater than 100." width="2430" height="1760" data-path="_assets/images/query/relational-fields-example-any-trace.png" />
</Frame>

To explore more examples related to using relational fields with the `anyX.` prefix, visit [Examples: Query for Traces](/investigate/query/examples-traces/#anyx-prefix).

#### Prefix: none

The `none.` prefix matches to a single span and excludes any traces that contain the matched span.
When you use it, additional filters in your query will search through only fields not in the matched `none.` span.

<Tip>
  * If you use multiple `none.` relational fields in the WHERE clause, Honeycomb will apply them all to the same span.
  * `none.` is not available in the GROUP BY clause.
</Tip>

So you might use a query that contains:

* **SELECT** `COUNT`
* **WHERE** `none.trace.parent_id does-not-exist`
* **GROUP BY** `trace.trace_id`

<Frame>
  <img src="https://mintcdn.com/honeycomb/oJe-ncVHXR8RRGAw/_assets/images/query/relational-fields-example-none-query.png?fit=max&auto=format&n=oJe-ncVHXR8RRGAw&q=85&s=f66872905aa9dd0d4b30afc8dc51ea6e" alt="Honeycomb Query Builder with the discussed query options entered." width="800" height="589" data-path="_assets/images/query/relational-fields-example-none-query.png" />
</Frame>

And you might see the following trace summary when you select a span from the query results:

<Frame>
  <img src="https://mintcdn.com/honeycomb/oJe-ncVHXR8RRGAw/_assets/images/query/relational-fields-example-none-trace.png?fit=max&auto=format&n=oJe-ncVHXR8RRGAw&q=85&s=4ebb09273855a6a675d751d51a196cc6" alt="A trace summary that displays multiple spans. At the top of the trace summary, the parent span is labeled as missing, which is expected." width="800" height="521" data-path="_assets/images/query/relational-fields-example-none-trace.png" />
</Frame>

To explore more examples related to using relational fields with the `none.` prefix, visit [Examples: Query for Traces](/investigate/query/examples-traces/#none-prefix).

#### Example: Using Relational Fields Prefixes Together

You can use all of the relational fields prefixes together to perform a more complex query.

So you might use a query that contains:

* **SELECT** `COUNT`
* **WHERE** `error exists` AND `root.name = /cart/checkout` AND `parent.duration_ms > 200` AND `any.name = getDiscounts`
* **GROUP BY** `any.k8s.pod.name`

<Frame>
  <img src="https://mintcdn.com/honeycomb/oJe-ncVHXR8RRGAw/_assets/images/query/relational-fields-example-root-parent-any-query.png?fit=max&auto=format&n=oJe-ncVHXR8RRGAw&q=85&s=b78ac90b60fbd3060ed4f1bd562c98da" alt="Honeycomb Query Builder with the discussed query options entered." width="1146" height="751" data-path="_assets/images/query/relational-fields-example-root-parent-any-query.png" />
</Frame>

And you might see the following trace summary when you select a span from the query results:

<Frame>
  <img src="https://mintcdn.com/honeycomb/oJe-ncVHXR8RRGAw/_assets/images/query/relational-fields-example-root-parent-any-trace.png?fit=max&auto=format&n=oJe-ncVHXR8RRGAw&q=85&s=3e54afdf50df9c3f2ad112b68c7771e6" alt="A trace summary that displays multiple spans. Some spans have been highlighted, including the root span named /cart/checkout and one of its child spans named getDiscounts. The duration_ms for a child span where its parent's duration_ms is greater than 200 has also been highlighted." width="2698" height="1688" data-path="_assets/images/query/relational-fields-example-root-parent-any-trace.png" />
</Frame>

To explore more examples related to using relational fields with relational fields, visit [Examples: Query for Traces](/investigate/query/examples-traces/#relational-fields).

## Troubleshooting

Refer to [Common Issues with Queries](/troubleshoot/common-issues/queries/).
