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

# ソートとページング

> orderBy 入力オブジェクトでクエリ結果をソートし、limit でページング — 命名規則、デフォルト、offset ベースのページング

## orderBy InputObject

各 Cube は `{Cube}OrderBy` 入力オブジェクトを生成し、`ascending` と `descending` フィールドを持ちます。各フィールドはディメンションパスをアンダースコアでつないだ `CompareFields` 列挙値を受け取ります:

```
{DimensionGroup}_{DimensionField}
```

ネストしたディメンションでは、レベルごとに結合します:

```
Block_Time
Trade_Buy_Amount
Trade_Buy_PriceInUSD
```

使用例:

```graphql theme={null}
orderBy: {descending: Block_Time}      # newest first
orderBy: {ascending: Trade_Buy_Amount}  # smallest amount first
```

### よく使う CompareFields の値

<div style={{ overflowX: 'auto', width: '100%' }}>
  | CompareFields の値       | 使用例                                           | Cube                                                                              | 説明           |
  | :--------------------- | :-------------------------------------------- | :-------------------------------------------------------------------------------- | :----------- |
  | `Block_Time`           | `orderBy: {descending: Block_Time}`           | DEXTrades, Transfers, BalanceUpdates, DEXPools, TokenSupplyUpdates, Pairs, Tokens | 新しい順         |
  | `Block_Time`           | `orderBy: {ascending: Block_Time}`            | DEXTrades, Transfers, BalanceUpdates, DEXPools, TokenSupplyUpdates, Pairs, Tokens | 古い順          |
  | `Interval_Time_Start`  | `orderBy: {ascending: Interval_Time_Start}`   | Pairs, Tokens                                                                     | 古い順（区間開始時刻）  |
  | `Trade_Buy_Amount`     | `orderBy: {descending: Trade_Buy_Amount}`     | DEXTrades                                                                         | 買い数量の大きい順    |
  | `Trade_Buy_PriceInUSD` | `orderBy: {descending: Trade_Buy_PriceInUSD}` | DEXTrades                                                                         | USD 価格の高い順   |
  | `Transfer_AmountInUSD` | `orderBy: {descending: Transfer_AmountInUSD}` | Transfers                                                                         | USD 転送額の大きい順 |
  | `LatestBalanceUSD`     | `orderBy: {descending: LatestBalanceUSD}`     | TokenHolders                                                                      | 保有額の大きい順     |
  | `BuyVolumeUSDState`    | `orderBy: {descending: BuyVolumeUSDState}`    | WalletTokenPnL                                                                    | 買いボリュームの大きい順 |
</div>

<Tip>
  [GraphQL IDE](https://ide.chainstream.io) のオートコンプリートで、Cube ごとに利用可能なすべての `CompareFields` を確認できます — `orderBy: {descending:` と入力すると IDE が候補を表示します。
</Tip>

### 使い方

`descending` または `ascending` のどちらか一方に `CompareFields` の値を指定した `orderBy` 入力オブジェクトを渡します:

```graphql theme={null}
query {
  Solana {
    DEXTrades(
      orderBy: {descending: Block_Time}
      limit: { count: 10 }
    ) {
      Block { Time }
      Trade { Buy { Amount PriceInUSD } }
    }
  }
}
```

<Note>
  `orderBy` は**1 組**の方向／フィールドのみ受け付けます。複数列ソートはサポートされず、一度に 1 ディメンションで並べ替えます。
</Note>

***

## limit 引数

`limit` 引数は返す行数を制御し、オフセットベースのページネーションをサポートします:

```graphql theme={null}
input LimitInput {
  count: Int   # Number of rows to return
  offset: Int  # Number of rows to skip
}
```

### 既定値と最大値

各 Cube には `limit` を省略したときの**既定**の件数と、**最大**の上限があります:

| Cube               | 既定の `count` | 最大 `count` |
| :----------------- | :---------- | :--------- |
| DEXTrades          | 25          | 10,000     |
| Transfers          | 25          | 10,000     |
| BalanceUpdates     | 25          | 10,000     |
| DEXPools           | 25          | 10,000     |
| TokenSupplyUpdates | 25          | 10,000     |
| Pairs              | 25          | 10,000     |
| Tokens             | 25          | 10,000     |
| DEXPoolEvents      | 25          | 10,000     |
| TokenHolders       | 25          | 10,000     |
| WalletTokenPnL     | 25          | 10,000     |

<Info>
  要求した `count` が最大を超える場合、サーバーは黙って最大値に切り詰めます。
</Info>

***

## オフセットベースのページネーション

`offset` で結果セットをページングします。パターンは次のとおりです。

* **ページ 1**: `limit: { count: 50, offset: 0 }`
* **ページ 2**: `limit: { count: 50, offset: 50 }`
* **ページ 3**: `limit: { count: 50, offset: 100 }`

### 例: トークン保有者のページング

<Tabs>
  <Tab title="ページ 1">
    ```graphql theme={null}
    query {
      Solana {
        TokenHolders(
          tokenAddress: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"
          orderBy: {descending: LatestBalanceUSD}
          limit: { count: 20, offset: 0 }
        ) {
          Holder { Address }
          LatestBalance
          LatestBalanceUSD
        }
      }
    }
    ```
  </Tab>

  <Tab title="ページ 2">
    ```graphql theme={null}
    query {
      Solana {
        TokenHolders(
          tokenAddress: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"
          orderBy: {descending: LatestBalanceUSD}
          limit: { count: 20, offset: 20 }
        ) {
          Holder { Address }
          LatestBalance
          LatestBalanceUSD
        }
      }
    }
    ```
  </Tab>
</Tabs>

### ページネーションのヒント

<AccordionGroup>
  <Accordion title="ページネーションには常に orderBy を付ける">
    安定した並び順がないと、ページ間で行がずれることがあります。決定的な順序になるよう、常に `limit` と `orderBy` を組み合わせてください。
  </Accordion>

  <Accordion title="深い offset は避ける">
    大きな `offset`（例: 50,000 以上）は、DB がスキャンしてスキップするため性能が落ちることがあります。非常に大きなデータセットでは、深くページングするより `where` でクエリを狭めてください。
  </Accordion>

  <Accordion title="count で結果の終端を判定する">
    1 ページの行数が要求した `count` より少なければ、データセットの終端に達しています。別法として、事前に総行数を得る `count` メトリクスフィールドも使えます。
  </Accordion>
</AccordionGroup>

***

## 実践例

### 直近の大口取引

Solana で買い価値が 10,000 ドル超の、直近 10 件の DEX 取引を取得:

```graphql theme={null}
query {
  Solana {
    DEXTrades(
      where: {
        Trade: { Buy: { PriceInUSD: { gt: 10000 } } }
      }
      orderBy: {descending: Block_Time}
      limit: { count: 10 }
    ) {
      Block { Time }
      Trade {
        Buy {
          Currency { MintAddress }
          Amount
          PriceInUSD
        }
        Dex { ProtocolName }
      }
    }
  }
}
```

### OHLC ローソク — 直近 60 分

トークンの 1 分足を時系列で取得:

```graphql theme={null}
query {
  Trading {
    Pairs(
      where: {
        Token: { Address: { is: "So11111111111111111111111111111111111111112" } }
        Market: { Network: { is: "sol" } }
        Block: { Time: { after: "2025-03-27T09:00:00Z" } }
      }
      orderBy: {ascending: Block_Time}
      limit: { count: 60 }
    ) {
      Block { Time }
      Price {
        Ohlc { Open High Low Close }
      }
      Volume { Usd }
      Stats { TradeCount }
    }
  }
}
```

### トップ 50 保有者

USD 残高でソートした上位 50 保有者:

```graphql theme={null}
query {
  Solana {
    TokenHolders(
      tokenAddress: "DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263"
      orderBy: {descending: LatestBalanceUSD}
      limit: { count: 50 }
    ) {
      Holder { Address }
      LatestBalance
      LatestBalanceUSD
      FirstSeen
      LastSeen
    }
  }
}
```

***

## 次のステップ

<CardGroup cols={2}>
  <Card title="フィルタリング" icon="filter" href="/jp/graphql/schema/filtering">
    並び順とフィルターを組み合わせて、精密な分析クエリを構築します。
  </Card>

  <Card title="メトリクスと集計" icon="chart-simple" href="/jp/graphql/schema/metrics-aggregation">
    count、sum、avg、min、max、uniq で並べたデータを集計します。
  </Card>
</CardGroup>
