# Named Query Structure

Use this page when you need exact syntax for a named query block.

## Model

```xml
<!--{{!
<lineitemsSOQL>
  <class>none</class>
  <queryname>TopLineItem</queryname>
  <soql>
    SELECT Name, Quantity, TotalPrice
    FROM OpportunityLineItem
    WHERE OpportunityId = '{{!Opportunity.Id}}'
    ORDER BY TotalPrice DESC
    LIMIT 1
  </soql>
  <filter id="1">TotalPrice >= 1000</filter>
</lineitemsSOQL>
}}-->
```

{% stepper %}
{% step %}
**`<!--{{!` and `}}-->`**

**Purpose**

These are S-Docs processing block markers.

* `<!--{{!` tells S-Docs to start processing the block
* `}}-->` tells S-Docs to stop processing the block

They also keep the block hidden if the template is opened outside S-Docs.
{% endstep %}

{% step %}
**`<lineitemsSOQL>`**

**Purpose**

This wrapper tells S-Docs to run a SOQL query during document generation.

For named queries, the goal is usually **data reuse**, not table output.

Key traits:

* runs a SOQL query at generation time
* can return one row or many rows
* lets you reuse returned values later in the template
* must include `<class>none</class>` when you do not want a rendered table
  {% endstep %}

{% step %}
**`<class>`**

**Purpose**

Set this to `none` for named queries.

```xml
<class>none</class>
```

This tells S-Docs to store the results without rendering a table.

If you omit this, S-Docs may try to output related list markup instead of keeping the query reusable.
{% endstep %}

{% step %}
**`<queryname>`**

**Purpose**

This assigns the reusable name for your query result.

```xml
<queryname>TopLineItem</queryname>
```

You will reference this name later in merge fields.

For example:

`{{!TopLineItem.Name}}`

Rules:

* use a unique name in the template
* keep the name short and descriptive
* match the spelling exactly in later merge fields
  {% endstep %}

{% step %}
**`<soql>`**

**Purpose**

This contains the exact SOQL query S-Docs should run.

```xml
<soql>
  SELECT Name, Quantity, TotalPrice
  FROM OpportunityLineItem
  WHERE OpportunityId = '{{!Opportunity.Id}}'
  ORDER BY TotalPrice DESC
  LIMIT 1
</soql>
```

This example returns the highest-value line item for the current opportunity.

Use `<soql>` when you need:

* specific fields
* filtering with `WHERE`
* sorting with `ORDER BY`
* one-row results with `LIMIT 1`
* aggregates like `COUNT()` or `SUM()`

Include every field you plan to reference later.
{% endstep %}

{% step %}
**`<filter>`**

**Purpose**

`<filter>` lets you define reusable conditions inside the same named query.

```xml
<filter id="1">TotalPrice >= 1000</filter>
```

You can then call that filter in a merge field:

`{{!FilteredItems.Name filter="1" offset="1"}}`

Use `filter` when you want multiple output variations from one result set.
{% endstep %}

{% step %}
**Merge field syntax**

**Purpose**

After the query runs, reference values with this pattern:

`{{!QueryName.FieldName}}`

Examples:

* `{{!TopLineItem.Name}}`
* `{{!TopLineItem.Quantity}}`
* `{{!LineItemStats.asum #,###.00}}`
* `{{!FilteredItems.Name filter="1" offset="2"}}`

Common parts:

* `QueryName` comes from `<queryname>`
* `FieldName` must come from the `SELECT` clause
* formatting comes after a space
* `filter` and `offset` are optional attributes
  {% endstep %}
  {% endstepper %}

### Merge field quick reference

| Pattern                                          | Use                                        |
| ------------------------------------------------ | ------------------------------------------ |
| `{{!QueryName.FieldName}}`                       | Return a field from the first matching row |
| `{{!QueryName.FieldName #,###.00}}`              | Format a numeric value                     |
| `{{!QueryName.FieldName filter="1"}}`            | Apply a named filter                       |
| `{{!QueryName.FieldName offset="2"}}`            | Return the second row                      |
| `{{!QueryName.FieldName filter="1" offset="2"}}` | Combine both                               |

### Format-specific variations

{% tabs %}
{% tab title="DOCX & PPTX" %}
Wrap both the query block and the merge fields in square brackets.

* Query block: `[{{!<lineitemsSOQL>...</lineitemsSOQL>}}]`
* Merge field: `[{{!QueryName.FieldName}}]`
  {% endtab %}

{% tab title="PDF-Upload" %}
Place the query block in the template's **Named Queries** setting.

Then place merge fields like `{{!QueryName.FieldName}}` on the PDF surface.
{% endtab %}
{% endtabs %}

### Summary table

| Part                       | Meaning                           |
| -------------------------- | --------------------------------- |
| `<!--{{!` / `}}-->`        | Starts and ends S-Docs processing |
| `<lineitemsSOQL>`          | Wraps the named query block       |
| `<class>none</class>`      | Prevents table output             |
| `<queryname>`              | Sets the reusable query name      |
| `<soql>`                   | Runs the actual SOQL query        |
| `<filter>`                 | Adds reusable filter logic        |
| `{{!QueryName.FieldName}}` | Reuses a returned value later     |

### Full example

```xml
<!--{{!
<lineitemsSOQL>
  <class>none</class>
  <queryname>TopLineItem</queryname>
  <soql>
    SELECT Name, Quantity, TotalPrice
    FROM OpportunityLineItem
    WHERE OpportunityId = '{{!Opportunity.Id}}'
    ORDER BY TotalPrice DESC
    LIMIT 1
  </soql>
</lineitemsSOQL>
}}-->

Top line item: {{!TopLineItem.Name}}
Quantity: {{!TopLineItem.Quantity}}
Total: ${{!TopLineItem.TotalPrice #,###.00}}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://help.sdocs.com/developer-hub/template-configuration-and-styling/reference-named-query-syntax/named-query-structure.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
