> ## Documentation Index
> Fetch the complete documentation index at: https://cubed3-feat-druid-driver-streaming.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Segments

> Segments are predefined, reusable filters that package common SQL predicates for use in queries and tooling.

You can use the `segments` parameter within [cubes][ref-ref-cubes] to define segments.
Segments are predefined filters. You can use segments to define complex filtering logic in SQL.

For example, users for one particular city can be treated as a segment:

<CodeGroup>
  ```yaml title="YAML" theme={null}
  cubes:
    - name: users
      # ...

      segments:
        - name: sf_users
          sql: "{CUBE}.location = 'San Francisco'"
  ```

  ```javascript title="JavaScript" theme={null}
  cube(`users`, {
    // ...
    segments: {
      sf_users: {
        sql: `${CUBE}.location = 'San Francisco'`
      }
    }
  })
  ```
</CodeGroup>

Or use segments to implement cross-column `OR` logic:

<CodeGroup>
  ```yaml title="YAML" theme={null}
  cubes:
    - name: users
      # ...

      segments:
        - name: sf_users
          sql: |
            {CUBE}.location = 'San Francisco' OR {CUBE}.state = 'CA'
  ```

  ```javascript title="JavaScript" theme={null}
  cube(`users`, {
    // ...

    segments: {
      sf_users: {
        sql: `
          ${CUBE}.location = 'San Francisco' OR
          ${CUBE}.state = 'CA'
        `
      }
    }
  })
  ```
</CodeGroup>

As with other cube member definitions, segments can be
[generated][ref-schema-gen]:

```javascript theme={null}
const userSegments = {
  sf_users: ["San Francisco", "CA"],
  ny_users: ["New York City", "NY"]
}

cube(`users`, {
  // ...

  segments: {
    ...Object.keys(userSegments)
      .map((segment) => ({
        [segment]: {
          sql: `${CUBE}.location = '${userSegments[segment][0]}' or ${CUBE}.state = '${userSegments[segment][1]}'`
        }
      }))
      .reduce((a, b) => ({ ...a, ...b }))
  }
})
```

After defining a segment, you can pass it in [query object][ref-backend-query]:

```json theme={null}
{
  "measures": ["users.count"],
  "segments": ["users.sf_users"]
}
```

## Parameters

### `name`

The `name` parameter serves as the identifier of a segment. It must be unique
among all segments, dimensions, and measures within a cube and follow the
[naming conventions][ref-naming].

<CodeGroup>
  ```yaml title="YAML" theme={null}
  cubes:
    - name: users
      # ...

      segments:
        - name: sf_users
          sql: "{CUBE}.location = 'San Francisco'"
  ```

  ```javascript title="JavaScript" theme={null}
  cube(`users`, {
    // ...

    segments: {
      sf_users: {
        sql: `${CUBE}.location = 'San Francisco'`
      }
    }
  })
  ```
</CodeGroup>

### `description`

This parameter provides a human-readable description of a segment.
When applicable, it will be displayed in [Playground][ref-playground] and exposed
to data consumers via [APIs and integrations][ref-apis].

<CodeGroup>
  ```yaml title="YAML" theme={null}
  cubes:
    - name: users
      # ...

      segments:
        - name: sf_users
          sql: "{CUBE}.location = 'San Francisco'"
          description: Users from San Francisco
  ```

  ```javascript title="JavaScript" theme={null}
  cube(`users`, {
    // ...

    segments: {
      sf_users: {
        sql: `${CUBE}.location = 'San Francisco'`,
        description: `Users from San Francisco`
      }
    }
  })
  ```
</CodeGroup>

### `public`

The `public` parameter is used to manage the visibility of a segment. Valid
values for `public` are `true` and `false`. When set to `false`, this segment
**cannot** be queried through the API. Defaults to `true`.

<CodeGroup>
  ```yaml title="YAML" theme={null}
  cubes:
    - name: users
      segments:
        - name: sf_users
          sql: "{CUBE}.location = 'San Francisco'"
          public: false
  ```

  ```javascript title="JavaScript" theme={null}
  cube(`users`, {
    segments: {
      sf_users: {
        sql: `${CUBE}.location = 'San Francisco'`,
        public: false
      }
    }
  })
  ```
</CodeGroup>

### `sql`

The `sql` parameter defines how a segment would filter out a subset of data. It
takes any SQL expression that would be valid within a `WHERE` statement.

<CodeGroup>
  ```yaml title="YAML" theme={null}
  cubes:
    - name: users
      # ...

      segments:
        - name: sf_users
          sql: "{CUBE}.location = 'San Francisco'"
  ```

  ```javascript title="JavaScript" theme={null}
  cube(`users`, {
    // ...

    segments: {
      sf_users: {
        sql: `${CUBE}.location = 'San Francisco'`
      }
    }
  })
  ```
</CodeGroup>

## Segments vs Dimension Filters

As segments are simply predefined filters, it can be difficult to determine when
to use segments instead of filters on dimensions.

Let's consider an example:

<CodeGroup>
  ```yaml title="YAML" theme={null}
  cubes:
    - name: users
      # ...

      dimensions:
        - name: location
          sql: location
          type: string

      segments:
        - name: sf_users
          sql: "{CUBE}.location = 'San Francisco'"
  ```

  ```javascript title="JavaScript" theme={null}
  cube(`users`, {
    // ...

    dimensions: {
      location: {
        sql: `location`,
        type: `string`
      }
    },

    segments: {
      sf_users: {
        sql: `${CUBE}.location = 'San Francisco'`
      }
    }
  })
  ```
</CodeGroup>

In this case following queries are equivalent:

```json theme={null}
{
  "measures": ["users.count"],
  "filters": [
    {
      "member": "users.location",
      "operator": "equals",
      "values": ["San Francisco"]
    }
  ]
}
```

and

```json theme={null}
{
  "measures": ["users.count"],
  "segments": ["users.sf_users"]
}
```

This case is a bad candidate for segment usage and a filter on a dimension works
better here. `users.location` filter value can change a lot for user queries and
`users.sf_users` segment won't be used much in this case.

A good candidate case for a segment is when you have a complex filtering
expression which can be reused for a lot of user queries. For example:

<CodeGroup>
  ```yaml title="YAML" theme={null}
  cubes:
    - name: users
      # ...

      segments:
        - name: sf_ny_users
          sql: |
            {CUBE}.location = 'San Francisco' OR {CUBE}.location like '%New York%'
  ```

  ```javascript title="JavaScript" theme={null}
  cube(`users`, {
    // ...

    segments: {
      sf_ny_users: {
        sql: `
          ${CUBE}.location = 'San Francisco' OR
          ${CUBE}.location like '%New York%'
        `
      }
    }
  })
  ```
</CodeGroup>

[ref-ref-cubes]: /reference/data-modeling/cube

[ref-backend-query]: /reference/core-data-apis/rest-api/query-format

[ref-schema-gen]: /recipes/data-modeling/using-dynamic-measures

[ref-naming]: /docs/data-modeling/syntax#naming

[ref-playground]: /docs/explore-analyze/playground

[ref-apis]: /reference
