# Aggregation Functions

Scanner supports some functions for basic aggregations.

Aggregation functions are invoked with the parentheses `()`, e.g. `count()`, although top-level parentheses are optional. E.g.:

```python
# These are all OK
* | stats countdistinct(foo, bar)
* | stats(countdistinct(foo, bar))
* | countdistinct foo, bar
* | countdistinct(foo, bar)
# This is a parse error
* | stats countdistinct foo, bar
```

Functions are chained onto text query filter clauses with the `|` (vertical pipe) operator, and can be attached to any legal query:

<pre class="language-python"><code class="lang-python"># get how many error responses occurred for each kubernetes pod
status_code >= 400 
| stats count() by kubernetes.container_name, kubernetes.pod_name

<strong># get how many different emails there are in the whole dataset
</strong><strong>* | countdistinct email
</strong>
# get how many AWS API calls were made to S3 or DynamoDB and returned an error
(eventSource: "s3" or eventSource: "dynamodb") and errorCode: *
| stats count() as errorCount

# get the average, median, and 90th percentile S3 request counts by IAM user
userIdentity.type: "IAMUser" and eventSource: "s3.amazonaws.com"
| stats count() as numReqs, userIdentity.arn by userIdentity.arn
| stats avg(numReqs), percentile(50, numReqs), percentile(90, numReqs)
</code></pre>

Function arguments can support either numeric or string values. Strings in function arguments may be specified as either bare words, or quoted strings. Bare words must begin with an alphabetical or `@%_` character, and cannot include whitespace or any of the following characters: `` :()"'<>=|,~{}!#` ``. They also can't be any reserved keywords (see [#reserved-keywords](#reserved-keywords "mention")).

```python
# These are all OK
* | max "num_events"
* | max num_events
* | max "3d_objects"
# These are parse errors
* | max 3d_objects
* | countdistinct [value]
```

Quoted strings in function arguments may be singly- or doubly-quoted, and support the [same escape sequences as in the filter query](/scanner/using-scanner-complete-feature-reference/querying-and-analysis/query-syntax.md#escape-sequences-for-strings). Note that here, the `*` character is simply treated as a character, since function argument strings don't support wildcarding.

#### Reserved Keywords

The following keywords are reserved in function arguments: `by`, `as`, `from`, `in`, `true`, `false`, `null`. Use quotes if you need to pass any of these values as strings to a function.


---

# 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://docs.scanner.dev/scanner/using-scanner-complete-feature-reference/querying-and-analysis/aggregation-functions.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.
